mirror of
https://github.com/tabler/tabler.git
synced 2026-10-12 05:06:55 +04:00
Add the Colorpicker screenshot scene and extend its docs
- docs: modal example, live preview, keyboard table, RTL and CSS usage
This commit is contained in:
1 parent
a778f4a169
commit
edc5a44415
2 files changed
+158
No files matched your search
@@ -7,6 +7,7 @@ related: [/ui/forms/elements, /ui/forms/color-check, /ui/plugins/date-picker]
|
||||
source: core/scss/ui/forms/_colorpicker.scss
|
||||
css-vars: colorpicker
|
||||
sass-vars: colorpicker
|
||||
added-in: '1.7.0'
|
||||
classnames:
|
||||
component:
|
||||
- class: colorpicker
|
||||
@@ -179,10 +180,52 @@ The swatch follows `.form-control-sm` and `.form-control-lg`, and the field keep
|
||||
|
||||
Inside a modal or an offcanvas the panel is appended to that dialog instead of `<body>`, so it opens above it and stays inside its focus trap. <kbd>Escape</kbd> closes the panel first, and the dialog on the next press.
|
||||
|
||||
<Example centered>
|
||||
<button type="button" class="btn" data-bs-toggle="modal" data-bs-target="#colorpicker-modal">Edit label</button>
|
||||
<div class="modal" id="colorpicker-modal" tabindex="-1" aria-labelledby="colorpicker-modal-title">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="colorpicker-modal-title">Edit label</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<label class="form-label" for="colorpicker-modal-color">Color</label>
|
||||
<div class="colorpicker">
|
||||
<input type="text" class="form-control" id="colorpicker-modal-color" data-bs-toggle="colorpicker" value="#d63939" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn me-auto" data-bs-dismiss="modal">Cancel</button>
|
||||
<button type="button" class="btn btn-primary" data-bs-dismiss="modal">Save</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Example>
|
||||
|
||||
Set `data-bs-container` to a selector when the panel has to live somewhere else, for example in a wrapper with its own stacking order.
|
||||
|
||||
### Dark mode
|
||||
|
||||
The panel is appended to `<body>`, outside the cascade of the field, so the plugin copies the nearest `data-bs-theme` to it and follows later changes. Set `data-bs-colorpicker-theme` to force a theme for the panel alone.
|
||||
|
||||
### Right-to-left
|
||||
|
||||
Nothing to set up. In a page with `dir="rtl"` the swatch moves to the other end of the field, the gradient and the sliders are mirrored, and the arrow keys follow the direction of the text.
|
||||
|
||||
### Use the color in CSS
|
||||
|
||||
The plugin writes the picked color to the `--tblr-colorpicker-value` custom property on the `.colorpicker` wrapper, or on the trigger when it is a button. That is what paints the swatch, and your own styles can read it too. The property is removed while the field is empty.
|
||||
|
||||
```css
|
||||
.my-label-preview {
|
||||
background-color: var(--tblr-colorpicker-value, transparent);
|
||||
}
|
||||
```
|
||||
|
||||
The element has to be inside the wrapper or the button to see the value. For anything else on the page, listen to the `change.bs.colorpicker` event, as in the live preview below.
|
||||
|
||||
## Examples
|
||||
|
||||
### Field with a label
|
||||
@@ -203,6 +246,38 @@ Use the picker like any other form field: a label, the input, and a hint below i
|
||||
</div>
|
||||
</Example>
|
||||
|
||||
### Live preview
|
||||
|
||||
Listen to `change.bs.colorpicker` on the field to use the color as it changes. Here the value becomes the primary color of the elements below.
|
||||
|
||||
<Example column>
|
||||
<div class="colorpicker">
|
||||
<input type="text" class="form-control" id="colorpicker-live" data-bs-toggle="colorpicker" value="#066fd1" aria-label="Primary color" />
|
||||
</div>
|
||||
<div class="d-flex flex-wrap align-items-center gap-3" id="colorpicker-live-preview">
|
||||
<button type="button" class="btn btn-primary">Button</button>
|
||||
<span class="badge bg-primary text-primary-fg">Badge</span>
|
||||
<span class="status status-primary">Status</span>
|
||||
<label class="form-check form-switch m-0">
|
||||
<input class="form-check-input" type="checkbox" checked />
|
||||
<span class="form-check-label">Switch</span>
|
||||
</label>
|
||||
</div>
|
||||
</Example>
|
||||
|
||||
```js
|
||||
const field = document.getElementById('colorpicker-live');
|
||||
const preview = document.getElementById('colorpicker-live-preview');
|
||||
|
||||
field.addEventListener('change.bs.colorpicker', (event) => {
|
||||
if (event.value) {
|
||||
preview.style.setProperty('--tblr-primary', event.value);
|
||||
} else {
|
||||
preview.style.removeProperty('--tblr-primary');
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## JavaScript
|
||||
|
||||
### Via data attributes
|
||||
@@ -283,6 +358,19 @@ document.getElementById('my-color').addEventListener('change.bs.colorpicker', (e
|
||||
- The panel is a `role="dialog"`. <kbd>Tab</kbd> from the field moves into it, the arrow keys move the handle in the gradient (<kbd>Shift</kbd> for bigger steps), the sliders are native range inputs, and <kbd>Escape</kbd> closes the panel and returns focus to the field.
|
||||
- The panel closes on a click outside and when focus moves to something outside it, so keyboard users are never trapped.
|
||||
|
||||
### Keyboard
|
||||
|
||||
| Key | Where | What it does |
|
||||
| --- | --- | --- |
|
||||
| <kbd>Tab</kbd> | Field | Moves focus into the open panel. |
|
||||
| <kbd>Tab</kbd> | Last control in the panel | Closes the panel and returns focus to the field. |
|
||||
| <kbd>Shift</kbd> + <kbd>Tab</kbd> | First control in the panel | Returns focus to the field and keeps the panel open. |
|
||||
| Arrow keys | Handle in the gradient | Change saturation and brightness by 1. |
|
||||
| <kbd>Shift</kbd> + arrow keys | Handle in the gradient | Change saturation and brightness by 10. |
|
||||
| Arrow keys | Hue and opacity sliders | Move the slider, as in any range input. |
|
||||
| <kbd>Enter</kbd> or <kbd>Space</kbd> | Swatch | Picks that color. |
|
||||
| <kbd>Escape</kbd> | Anywhere | Closes the panel. Inside a modal, the modal stays open. |
|
||||
|
||||
## Migration from Coloris
|
||||
|
||||
Until version 1.6 the color picker was the [Coloris](https://github.com/melloware/coloris-npm) library, restyled in `tabler-vendors.css`. It still ships in `dist/libs` and keeps working, but it will be removed in 2.0. To move a field to the plugin:
|
||||
@@ -291,3 +379,20 @@ Until version 1.6 the color picker was the [Coloris](https://github.com/mellowar
|
||||
- Wrap the input in `.colorpicker` and add `data-bs-toggle="colorpicker"`.
|
||||
- Move the options to `data-bs-*` attributes. `el` and `setInstance()` are gone, because every field has its own instance. `themeMode`, `rtl` and `margin` are handled by the theme and the text direction. `selectInput` has no equivalent. `format: 'mixed'` becomes `format="auto"`.
|
||||
- Replace the `coloris:pick` listener with `change.bs.colorpicker` on the field, or with the native `input` event.
|
||||
|
||||
<script>{`
|
||||
window.addEventListener('load', function () {
|
||||
const field = document.getElementById('colorpicker-live');
|
||||
const preview = document.getElementById('colorpicker-live-preview');
|
||||
|
||||
if (!field || !preview) return;
|
||||
|
||||
field.addEventListener('change.bs.colorpicker', function (event) {
|
||||
if (event.value) {
|
||||
preview.style.setProperty('--tblr-primary', event.value);
|
||||
} else {
|
||||
preview.style.removeProperty('--tblr-primary');
|
||||
}
|
||||
});
|
||||
});
|
||||
`}</script>
|
||||
@@ -0,0 +1,53 @@
|
||||
---
|
||||
// The Colorpicker plugin added in 1.7: a label form with the color field and
|
||||
// its panel open under it, opacity slider and format select included. The
|
||||
// panel is opened here rather than left to a focus the capture tool cannot
|
||||
// make, and the fake cursor rests on the handle in the gradient.
|
||||
import ScreenshotLayout from '../layouts/ScreenshotLayout.astro'
|
||||
import Card from '@ui/Card.astro'
|
||||
import CardBody from '@ui/CardBody.astro'
|
||||
import Colorpicker from '@ui/Colorpicker.astro'
|
||||
import FormGroup from '@ui/FormGroup.astro'
|
||||
---
|
||||
|
||||
<ScreenshotLayout title="Color picker" columns={1}>
|
||||
<Card>
|
||||
<CardBody>
|
||||
<FormGroup label="Name" for="colorpicker-name">
|
||||
<input type="text" class="form-control" id="colorpicker-name" value="Design" />
|
||||
</FormGroup>
|
||||
<FormGroup label="Color" for="colorpicker-color" class="mb-0">
|
||||
<Colorpicker value="#ae3ec9cc" alpha formatToggle id="colorpicker-color" />
|
||||
</FormGroup>
|
||||
</CardBody>
|
||||
</Card>
|
||||
|
||||
<!-- The panel hangs below the card, so the card moves up to keep the pair
|
||||
centred in the frame and the panel clear of the logo. -->
|
||||
<style is:inline>
|
||||
[data-screenshot-target] {
|
||||
margin-bottom: 23rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script is:inline>
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const input = document.getElementById('colorpicker-color')
|
||||
if (!input || !window.tabler?.Colorpicker) return
|
||||
|
||||
// The panel lives in the card, not in <body>: the capture hides the
|
||||
// theme toggle after the page is ready, which moves the frame, and a
|
||||
// panel placed against <body> would stay where the field used to be.
|
||||
new window.tabler.Colorpicker(input, { container: input.closest('.card') }).show().then(() => {
|
||||
const marker = document.querySelector('.colorpicker-panel .colorpicker-marker')
|
||||
if (!marker) return
|
||||
|
||||
const cursor = document.createElement('span')
|
||||
cursor.className = 'cursor'
|
||||
cursor.style.top = '70%'
|
||||
cursor.style.left = '60%'
|
||||
marker.append(cursor)
|
||||
})
|
||||
})
|
||||
</script>
|
||||
</ScreenshotLayout>
|
||||
Reference in new issue
Block a user