Browse Source

Add new color picker component using `coloris.js` library (#1575)

Paweł Kuna 2 years ago
parent
commit
be146073b9

+ 5 - 0
.changeset/thin-eagles-mix.md

@@ -0,0 +1,5 @@
+---
+"@tabler/core": patch
+---
+
+Add new color picker component using `coloris.js` library

+ 1 - 1
gulpfile.js

@@ -448,7 +448,7 @@ gulp.task('copy-libs', (cb) => {
 	files.forEach((file) => {
 		if (!file.match(/^https?/)) {
 			let dirname = path.dirname(file).replace('@', '')
-			let cmd = `mkdir -p "${distDir}/libs/${dirname}" && cp -r node_modules/${dirname}/* ${distDir}/libs/${dirname}`
+			let cmd = `mkdir -p "${distDir}/libs/${dirname}" && cp -r node_modules/${path.dirname(file)}/* ${distDir}/libs/${dirname}`
 
 			cp.exec(cmd)
 		}

+ 8 - 3
package.json

@@ -131,6 +131,7 @@
     ]
   },
   "devDependencies": {
+    "@melloware/coloris": "^0.19.1",
     "@babel/core": "^7.21.8",
     "@babel/preset-env": "^7.21.5",
     "@changesets/cli": "^2.26.1",
@@ -179,13 +180,13 @@
     "rollup-plugin-babel": "^4.4.0",
     "rollup-plugin-cleanup": "^3.2.1",
     "sass": "^1.62.1",
+    "star-rating.js": "^4.3.0",
     "tinymce": "^6.4.2",
     "tom-select": "^2.2.2",
     "vinyl-buffer": "^1.0.1",
     "vinyl-source-stream": "^2.0.0",
     "yaml": "^2.2.2",
-    "yargs": "^17.7.2",
-    "star-rating.js": "^4.3.0"
+    "yargs": "^17.7.2"
   },
   "dependencies": {
     "@popperjs/core": "^2.11.7",
@@ -206,11 +207,15 @@
     "litepicker": "^2.0.12",
     "nouislider": "^15.7.0",
     "plyr": "^3.7.8",
+    "star-rating.js": "^4.3.0",
     "tinymce": "^6.4.2",
     "tom-select": "^2.2.2",
-    "star-rating.js": "^4.3.0"
+    "@melloware/coloris": "^0.19.1"
   },
   "peerDependenciesMeta": {
+    "@melloware/coloris": {
+      "optional": true
+    },
     "apexcharts": {
       "optional": true
     },

+ 7 - 0
pnpm-lock.yaml

@@ -21,6 +21,9 @@ devDependencies:
   '@changesets/cli':
     specifier: ^2.26.1
     version: 2.26.1
+  '@melloware/coloris':
+    specifier: ^0.19.1
+    version: 0.19.1
   '@rollup/plugin-commonjs':
     specifier: ^24.1.0
     version: 24.1.0([email protected])
@@ -1598,6 +1601,10 @@ packages:
       read-yaml-file: 1.1.0
     dev: true
 
+  /@melloware/[email protected]:
+    resolution: {integrity: sha512-7C1ue136iQw3UCLy5GoCxXR+u4F1eB0MMmpAwUH2okdQwmdjVNd+OmIQBKVDbM78lMFFJxzvtilWkYV/l8/4rw==}
+    dev: true
+
   /@nodelib/[email protected]:
     resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
     engines: {node: '>= 8'}

+ 5 - 3
src/pages/_data/libs.json

@@ -20,16 +20,18 @@
     "jsvectormap-world": "jsvectormap/dist/maps/world.js",
     "jsvectormap-world-merc": "jsvectormap/dist/maps/world-merc.js",
     "fslightbox": "fslightbox/index.js",
-    "tinymce" :"tinymce/tinymce.min.js",
+    "tinymce": "tinymce/tinymce.min.js",
     "plyr": "plyr/dist/plyr.min.js",
     "dropzone": "dropzone/dist/dropzone-min.js",
-    "star-rating.js": "star-rating.js/dist/star-rating.min.js"
+    "star-rating.js": "star-rating.js/dist/star-rating.min.js",
+    "coloris.js": "@melloware/coloris/dist/umd/coloris.min.js"
   },
   "css": {
     "mapbox": "https://api.mapbox.com/mapbox-gl-js/v1.8.0/mapbox-gl.css",
     "dropzone": "dropzone/dist/dropzone.css",
     "plyr": "plyr/dist/plyr.css",
-    "star-rating.js": "star-rating.js/dist/star-rating.min.css"
+    "star-rating.js": "star-rating.js/dist/star-rating.min.css",
+    "coloris.js": "@melloware/coloris/dist/coloris.min.css"
   },
   "js-copy": {
     "tinymce" :"tinymce/*"

+ 74 - 73
src/pages/_data/menu.yml

@@ -11,6 +11,33 @@ base:
     accordion:
       title: Accordion
       url: accordion.html
+    authentication:
+      title: Authentication
+      children:
+        sign-in:
+          title: Sign in
+          url: sign-in.html
+        sign-in-link:
+          title: Sign in link
+          url: sign-in-link.html
+        sign-in-illustration:
+          title: Sign in with illustration
+          url: sign-in-illustration.html
+        sign-in-cover:
+          title: Sign in with cover
+          url: sign-in-cover.html
+        sign-up:
+          title: Sign up
+          url: sign-up.html
+        forgot-password:
+          title: Forgot password
+          url: forgot-password.html
+        terms-of-service:
+          title: Terms of service
+          url: terms-of-service.html
+        auth-lock:
+          title: Lock screen
+          url: auth-lock.html
     blank:
       title: Blank page
       url: blank.html
@@ -35,9 +62,20 @@ base:
         masonry:
           url: cards-masonry.html
           title: Cards Masonry
+    carousel:
+      title: Carousel
+      url: carousel.html
+      badge: New
+    charts:
+      url: charts.html
+      title: Charts
     colors:
       url: colors.html
       title: Colors
+    colorpicker:
+      url: colorpicker.html
+      title: Color picker
+      badge: New
     datagrid:
       url: datagrid.html
       title: Data grid
@@ -49,25 +87,55 @@ base:
     dropdowns:
       url: dropdowns.html
       title: Dropdowns
+    dropzone:
+      title: Dropzone
+      url: dropzone.html
+      badge: New
+    error:
+      title: Error pages
+      children:
+        404:
+          url: error-404.html
+          title: 404 page
+        500:
+          url: error-500.html
+          title: 500 page
+        maintenance:
+          url: error-maintenance.html
+          title: Maintenance page
+    plyr:
+      title: Inline player
+      badge: New
+      url: inline-player.html
+    lightbox:
+      title: Lightbox
+      url: lightbox.html
+      badge: New
+    lists:
+      title: Lists
+      url: lists.html
     modals:
       url: modals.html
-      title: Modals
+      title: Modal
     maps:
       url: maps.html
-      title: Maps
+      title: Map
     map-fullsize:
       url: map-fullsize.html
       title: Map fullsize
     maps-vector:
       url: maps-vector.html
-      title: Vector maps
+      title: Map vector
       badge: New
+    markdown:
+      title: Markdown
+      url: markdown.html
     navigation:
       url: navigation.html
       title: Navigation
-    charts:
-      url: charts.html
-      title: Charts
+    offcanvas:
+      title: Offcanvas
+      url: offcanvas.html
     pagination:
       url: pagination.html
       title: Pagination
@@ -89,80 +157,13 @@ base:
     tables:
       url: tables.html
       title: Tables
-    carousel:
-      title: Carousel
-      url: carousel.html
-      badge: New
-    lists:
-      title: Lists
-      url: lists.html
     typography:
       title: Typography
       url: typography.html
-    offcanvas:
-      title: Offcanvas
-      url: offcanvas.html
-    markdown:
-      title: Markdown
-      url: markdown.html
-    dropzone:
-      title: Dropzone
-      url: dropzone.html
-      badge: New
-    lightbox:
-      title: Lightbox
-      url: lightbox.html
-      badge: New
     tinymce:
       title: TinyMCE
       url: tinymce.html
       badge: New
-    plyr:
-      title: Inline player
-      badge: New
-      url: inline-player.html
-
-    authentication:
-      title: Authentication
-      children:
-        sign-in:
-          title: Sign in
-          url: sign-in.html
-        sign-in-link:
-          title: Sign in link
-          url: sign-in-link.html
-        sign-in-illustration:
-          title: Sign in with illustration
-          url: sign-in-illustration.html
-        sign-in-cover:
-          title: Sign in with cover
-          url: sign-in-cover.html
-        sign-up:
-          title: Sign up
-          url: sign-up.html
-        forgot-password:
-          title: Forgot password
-          url: forgot-password.html
-        terms-of-service:
-          title: Terms of service
-          url: terms-of-service.html
-        auth-lock:
-          title: Lock screen
-          url: auth-lock.html
-
-    error:
-      title: Error pages
-      icon: file-minus
-      children:
-        404:
-          url: error-404.html
-          title: 404 page
-        500:
-          url: error-500.html
-          title: 500 page
-        maintenance:
-          url: error-maintenance.html
-          title: Maintenance page
 
 forms:
   url: form-elements.html

+ 39 - 0
src/pages/_includes/ui/colorpicker.html

@@ -0,0 +1,39 @@
+{% assign id = include.id | default: 'default' %}
+{% assign alpha = include.alpha | default: false %}
+{% assign format = include.format | default: false %}
+
+<input type="text" class="form-control d-block{% if include.class %} {{ include.class }}{% endif %}" id="colorpicker-{{ id }}" value="{{ include.value }}" />
+
+{% capture_global scripts %}
+<script>
+	// @formatter:off
+	document.addEventListener("DOMContentLoaded", function () {
+		{% if jekyll.environment == 'development' %}
+		window.tabler_colorpicker = window.tabler_colorpicker || {};
+		{% endif %}
+		
+		window.Coloris && ({% if jekyll.environment == 'development' %}window.tabler_colorpicker["colorpicker-{{ id }}"] = {% endif %}Coloris({
+			el:  "#colorpicker-{{ id }}",
+			selectInput: false,
+			alpha: {% if alpha %}true{% else %}false{% endif %},
+			{% if format %}format: "{{ format }}",{% endif %}
+			{% if include['swatches-only'] %}swatchesOnly: true,{% endif %}
+			swatches: [
+				"#206bc4",
+				"#45aaf2",
+				"#6574cd",
+				"#a55eea",
+				"#f66d9b",
+				"#fa4654",
+				"#fd9644",
+				"#f1c40f",
+				"#7bd235",
+				"#5eba00",
+				"#2bcbba",
+				"#17a2b8",
+			],
+		}))
+	})
+	// @formatter:on
+</script>
+{% endcapture_global %}

+ 4 - 0
src/pages/_plugins/jekyll-filters.rb

@@ -119,6 +119,10 @@ module Jekyll
     def htmlbeautifier(output)
       HtmlBeautifier.beautify output
     end
+
+    def hex_to_rgb(hex)
+      hex.match(/^#(..)(..)(..)$/).captures.map(&:hex)
+    end
   end
 end
 

+ 21 - 0
src/pages/colorpicker.html

@@ -0,0 +1,21 @@
+---
+title: Color picker
+page-header: Color picker
+menu: base.colorpicker
+libs: coloris.js
+---
+
+{% assign colors = "#206bc4,#45aaf2,#6574cd,#a55eea,#f66d9b,#fa4654,#fd9644,#f1c40f,#7bd235,#5eba00,#2bcbba,#17a2b8" | split: "," %}
+
+<div class="card">
+	<div class="card-body">
+		<h3 class="card-title">Basic</h3>
+		<div class="row g-3">
+			{% for color in colors %}
+			<div class="col-2">
+				<div>{% include ui/colorpicker.html value=color id=forloop.index format="hex" %}</div>
+			</div>
+			{% endfor %}
+		</div>
+	</div>
+</div>

+ 10 - 2
src/scss/_variables.scss

@@ -457,6 +457,14 @@ $shadows: (
 
 $box-shadow-inset: 0 0 transparent !default;
 
+// Focus
+$focus-ring-width: 0.25rem !default;
+$focus-ring-opacity: 0.25 !default;
+$focus-ring-color: rgba(var(--#{$prefix}primary-rgb), $focus-ring-opacity) !default;
+$focus-ring-blur: 0 !default;
+$focus-ring-border-color: rgba(var(--#{$prefix}primary-rgb), 50%) !default;
+$focus-ring-box-shadow: 0 0 $focus-ring-blur $focus-ring-width $focus-ring-color !default;
+
 // Transitions
 $transition-time: 0.3s !default;
 
@@ -529,8 +537,8 @@ $input-height: null !default;
 $input-height-sm: null !default;
 $input-height-lg: null !default;
 $input-border-radius: var(--#{$prefix}border-radius) !default;
-$input-color: inherit !default;
-$input-focus-color: inherit !default;
+$input-color: var(--#{$prefix}body-color) !default;
+$input-focus-color: var(--#{$prefix}body-color) !default;
 
 // Buttons
 $btn-disabled-opacity: 0.4 !default;

+ 9 - 0
src/scss/mixins/_mixins.scss

@@ -56,4 +56,13 @@
   display: flex;
   flex-wrap: wrap;
   gap: var(--#{$prefix}list-gap);
+}
+
+@mixin focus-ring($show-border: false) {
+  outline: 0;
+  box-shadow: $focus-ring-box-shadow;
+
+  @if($show-border) {
+    border-color: $focus-ring-border-color;
+  }
 }

+ 1 - 0
src/scss/tabler-vendors.scss

@@ -10,3 +10,4 @@
 @import "vendor/plyr";
 @import "vendor/tinymce";
 @import "vendor/stars-rating";
+@import "vendor/coloris";

+ 67 - 0
src/scss/vendor/_coloris.scss

@@ -0,0 +1,67 @@
+.clr-picker {
+  box-shadow: var(--#{$prefix}shadow-dropdown);
+  background-color: var(--#{$prefix}bg-surface);
+}
+
+input.clr-color {
+  border-radius: var(--#{$prefix}border-radius);
+  color: var(--#{$prefix}body-color);
+  border-color: var(--#{$prefix}border-color);
+  background: transparent;
+
+  &:focus {
+    @include focus-ring(true);
+  }
+}
+
+.clr-swatches {
+  button {
+    border-radius: var(--#{$prefix}border-radius);
+    padding: 0 2px 4px 2px;
+
+    &:focus {
+      @include focus-ring;
+    }
+  }
+}
+
+.clr-preview {
+  border-radius: var(--#{$prefix}border-radius);
+  overflow: visible;
+
+  button,
+  &:before,
+  &:after {
+    border-radius: var(--#{$prefix}border-radius);
+  }
+
+  button {
+    &:focus {
+      @include focus-ring;
+    }
+  }
+}
+
+.clr-field {
+  display: block;
+  
+  button {
+    width: 1.5rem;
+    height: 1.5rem;
+    left: 6px;
+    right: auto;
+    border-radius: var(--#{$prefix}border-radius);
+
+    &:after {
+      box-shadow: inset 0 0 0 1px var(--#{$prefix}border-color-translucent);
+    }
+
+    &:focus {
+      @include focus-ring;
+    }
+  }
+
+  input {
+    padding-left: 2.5rem;
+  }
+}