@syware/jlib 0.0.0-stage → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +133 -2
- package/dist/all.d.ts +1 -0
- package/dist/all.js +75 -0
- package/dist/atoms/jl-avatar.css_raw.js +3 -0
- package/dist/atoms/jl-avatar.d.ts +52 -0
- package/dist/atoms/jl-avatar.js +167 -0
- package/dist/atoms/jl-badge.css_raw.js +3 -0
- package/dist/atoms/jl-badge.d.ts +32 -0
- package/dist/atoms/jl-badge.js +60 -0
- package/dist/atoms/jl-button.css_raw.js +3 -0
- package/dist/atoms/jl-button.d.ts +70 -0
- package/dist/atoms/jl-button.js +146 -0
- package/dist/atoms/jl-checkbox.css_raw.js +3 -0
- package/dist/atoms/jl-checkbox.d.ts +61 -0
- package/dist/atoms/jl-checkbox.js +149 -0
- package/dist/atoms/jl-chip.css_raw.js +3 -0
- package/dist/atoms/jl-chip.d.ts +59 -0
- package/dist/atoms/jl-chip.js +164 -0
- package/dist/atoms/jl-divider.css_raw.js +3 -0
- package/dist/atoms/jl-divider.d.ts +26 -0
- package/dist/atoms/jl-divider.js +59 -0
- package/dist/atoms/jl-icon.css_raw.js +3 -0
- package/dist/atoms/jl-icon.d.ts +25 -0
- package/dist/atoms/jl-icon.js +41 -0
- package/dist/atoms/jl-input.css_raw.js +3 -0
- package/dist/atoms/jl-input.d.ts +112 -0
- package/dist/atoms/jl-input.js +202 -0
- package/dist/atoms/jl-kbd.css_raw.js +3 -0
- package/dist/atoms/jl-kbd.d.ts +17 -0
- package/dist/atoms/jl-kbd.js +62 -0
- package/dist/atoms/jl-link.css_raw.js +3 -0
- package/dist/atoms/jl-link.d.ts +37 -0
- package/dist/atoms/jl-link.js +86 -0
- package/dist/atoms/jl-progress-ring.css_raw.js +3 -0
- package/dist/atoms/jl-progress-ring.d.ts +49 -0
- package/dist/atoms/jl-progress-ring.js +132 -0
- package/dist/atoms/jl-progress.css_raw.js +3 -0
- package/dist/atoms/jl-progress.d.ts +43 -0
- package/dist/atoms/jl-progress.js +109 -0
- package/dist/atoms/jl-rating.css_raw.js +3 -0
- package/dist/atoms/jl-rating.d.ts +73 -0
- package/dist/atoms/jl-rating.js +184 -0
- package/dist/atoms/jl-select.css_raw.js +3 -0
- package/dist/atoms/jl-select.d.ts +70 -0
- package/dist/atoms/jl-select.js +146 -0
- package/dist/atoms/jl-skeleton.css_raw.js +3 -0
- package/dist/atoms/jl-skeleton.d.ts +34 -0
- package/dist/atoms/jl-skeleton.js +63 -0
- package/dist/atoms/jl-slider.css_raw.js +3 -0
- package/dist/atoms/jl-slider.d.ts +65 -0
- package/dist/atoms/jl-slider.js +143 -0
- package/dist/atoms/jl-spinner.css_raw.js +3 -0
- package/dist/atoms/jl-spinner.d.ts +16 -0
- package/dist/atoms/jl-spinner.js +26 -0
- package/dist/atoms/jl-switch.css_raw.js +3 -0
- package/dist/atoms/jl-switch.d.ts +57 -0
- package/dist/atoms/jl-switch.js +125 -0
- package/dist/atoms/jl-textarea.css_raw.js +3 -0
- package/dist/atoms/jl-textarea.d.ts +81 -0
- package/dist/atoms/jl-textarea.js +148 -0
- package/dist/base/jl-element.d.ts +16 -0
- package/dist/base/jl-element.js +35 -0
- package/dist/base/jl-form-control.d.ts +29 -0
- package/dist/base/jl-form-control.js +44 -0
- package/dist/index.d.ts +119 -0
- package/dist/index.js +72 -0
- package/dist/lib/arrow.d.ts +6 -0
- package/dist/lib/arrow.js +15 -0
- package/dist/lib/attributes.d.ts +9 -0
- package/dist/lib/attributes.js +22 -0
- package/dist/lib/avatar.d.ts +11 -0
- package/dist/lib/avatar.js +37 -0
- package/dist/lib/calendar.d.ts +48 -0
- package/dist/lib/calendar.js +166 -0
- package/dist/lib/css-length.d.ts +2 -0
- package/dist/lib/css-length.js +8 -0
- package/dist/lib/define.d.ts +9 -0
- package/dist/lib/define.js +9 -0
- package/dist/lib/dom.d.ts +4 -0
- package/dist/lib/dom.js +16 -0
- package/dist/lib/files.d.ts +18 -0
- package/dist/lib/files.js +89 -0
- package/dist/lib/floating.d.ts +13 -0
- package/dist/lib/floating.js +127 -0
- package/dist/lib/fuzzy.d.ts +26 -0
- package/dist/lib/fuzzy.js +149 -0
- package/dist/lib/highlight.d.ts +5 -0
- package/dist/lib/highlight.js +267 -0
- package/dist/lib/hotkey.d.ts +9 -0
- package/dist/lib/hotkey.js +101 -0
- package/dist/lib/icon-set.d.ts +95 -0
- package/dist/lib/icon-set.js +97 -0
- package/dist/lib/icons.d.ts +12 -0
- package/dist/lib/icons.js +39 -0
- package/dist/lib/indicator.d.ts +6 -0
- package/dist/lib/indicator.js +18 -0
- package/dist/lib/keep-in-view.d.ts +5 -0
- package/dist/lib/keep-in-view.js +15 -0
- package/dist/lib/key-shortcut.d.ts +20 -0
- package/dist/lib/key-shortcut.js +100 -0
- package/dist/lib/keycaps.d.ts +8 -0
- package/dist/lib/keycaps.js +162 -0
- package/dist/lib/locale.d.ts +4 -0
- package/dist/lib/locale.js +13 -0
- package/dist/lib/nav-tree.d.ts +9 -0
- package/dist/lib/nav-tree.js +30 -0
- package/dist/lib/numeric.d.ts +20 -0
- package/dist/lib/numeric.js +50 -0
- package/dist/lib/option-filter.d.ts +29 -0
- package/dist/lib/option-filter.js +108 -0
- package/dist/lib/option-groups.d.ts +6 -0
- package/dist/lib/option-groups.js +26 -0
- package/dist/lib/options.d.ts +5 -0
- package/dist/lib/options.js +24 -0
- package/dist/lib/pagination.d.ts +9 -0
- package/dist/lib/pagination.js +52 -0
- package/dist/lib/palette.d.ts +8 -0
- package/dist/lib/palette.js +46 -0
- package/dist/lib/progress.d.ts +20 -0
- package/dist/lib/progress.js +33 -0
- package/dist/lib/rating.d.ts +7 -0
- package/dist/lib/rating.js +26 -0
- package/dist/lib/roving-index.d.ts +10 -0
- package/dist/lib/roving-index.js +32 -0
- package/dist/lib/roving.d.ts +11 -0
- package/dist/lib/roving.js +21 -0
- package/dist/lib/slots.d.ts +2 -0
- package/dist/lib/slots.js +6 -0
- package/dist/lib/sparkline.d.ts +11 -0
- package/dist/lib/sparkline.js +42 -0
- package/dist/lib/split.d.ts +12 -0
- package/dist/lib/split.js +37 -0
- package/dist/lib/surface.d.ts +7 -0
- package/dist/lib/surface.js +28 -0
- package/dist/lib/table.d.ts +30 -0
- package/dist/lib/table.js +110 -0
- package/dist/lib/tags.d.ts +14 -0
- package/dist/lib/tags.js +29 -0
- package/dist/lib/text.d.ts +5 -0
- package/dist/lib/text.js +13 -0
- package/dist/lib/tokens.d.ts +5 -0
- package/dist/lib/tokens.js +15 -0
- package/dist/lib/tree.d.ts +16 -0
- package/dist/lib/tree.js +89 -0
- package/dist/lib/trend.d.ts +3 -0
- package/dist/lib/trend.js +15 -0
- package/dist/lib/trigger.d.ts +11 -0
- package/dist/lib/trigger.js +34 -0
- package/dist/molecules/jl-accordion-item.css_raw.js +3 -0
- package/dist/molecules/jl-accordion-item.d.ts +34 -0
- package/dist/molecules/jl-accordion-item.js +82 -0
- package/dist/molecules/jl-accordion.css_raw.js +3 -0
- package/dist/molecules/jl-accordion.d.ts +27 -0
- package/dist/molecules/jl-accordion.js +61 -0
- package/dist/molecules/jl-alert.css_raw.js +3 -0
- package/dist/molecules/jl-alert.d.ts +38 -0
- package/dist/molecules/jl-alert.js +131 -0
- package/dist/molecules/jl-avatar-group.css_raw.js +3 -0
- package/dist/molecules/jl-avatar-group.d.ts +28 -0
- package/dist/molecules/jl-avatar-group.js +69 -0
- package/dist/molecules/jl-breadcrumb.css_raw.js +3 -0
- package/dist/molecules/jl-breadcrumb.d.ts +35 -0
- package/dist/molecules/jl-breadcrumb.js +126 -0
- package/dist/molecules/jl-calendar.css_raw.js +3 -0
- package/dist/molecules/jl-calendar.d.ts +101 -0
- package/dist/molecules/jl-calendar.js +314 -0
- package/dist/molecules/jl-card.css_raw.js +3 -0
- package/dist/molecules/jl-card.d.ts +46 -0
- package/dist/molecules/jl-card.js +172 -0
- package/dist/molecules/jl-code-block.css_raw.js +3 -0
- package/dist/molecules/jl-code-block.d.ts +44 -0
- package/dist/molecules/jl-code-block.js +106 -0
- package/dist/molecules/jl-combobox.css_raw.js +3 -0
- package/dist/molecules/jl-combobox.d.ts +120 -0
- package/dist/molecules/jl-combobox.js +450 -0
- package/dist/molecules/jl-copy-button.css_raw.js +3 -0
- package/dist/molecules/jl-copy-button.d.ts +31 -0
- package/dist/molecules/jl-copy-button.js +69 -0
- package/dist/molecules/jl-date-picker.css_raw.js +3 -0
- package/dist/molecules/jl-date-picker.d.ts +109 -0
- package/dist/molecules/jl-date-picker.js +322 -0
- package/dist/molecules/jl-empty.css_raw.js +3 -0
- package/dist/molecules/jl-empty.d.ts +32 -0
- package/dist/molecules/jl-empty.js +94 -0
- package/dist/molecules/jl-field.css_raw.js +3 -0
- package/dist/molecules/jl-field.d.ts +49 -0
- package/dist/molecules/jl-field.js +147 -0
- package/dist/molecules/jl-file-drop.css_raw.js +3 -0
- package/dist/molecules/jl-file-drop.d.ts +93 -0
- package/dist/molecules/jl-file-drop.js +366 -0
- package/dist/molecules/jl-list-item.css_raw.js +3 -0
- package/dist/molecules/jl-list-item.d.ts +56 -0
- package/dist/molecules/jl-list-item.js +176 -0
- package/dist/molecules/jl-menu.css_raw.js +3 -0
- package/dist/molecules/jl-menu.d.ts +62 -0
- package/dist/molecules/jl-menu.js +288 -0
- package/dist/molecules/jl-number-input.css_raw.js +3 -0
- package/dist/molecules/jl-number-input.d.ts +81 -0
- package/dist/molecules/jl-number-input.js +220 -0
- package/dist/molecules/jl-pagination.css_raw.js +3 -0
- package/dist/molecules/jl-pagination.d.ts +59 -0
- package/dist/molecules/jl-pagination.js +172 -0
- package/dist/molecules/jl-popover.css_raw.js +3 -0
- package/dist/molecules/jl-popover.d.ts +49 -0
- package/dist/molecules/jl-popover.js +152 -0
- package/dist/molecules/jl-radio-group.css_raw.js +3 -0
- package/dist/molecules/jl-radio-group.d.ts +71 -0
- package/dist/molecules/jl-radio-group.js +202 -0
- package/dist/molecules/jl-search.css_raw.js +3 -0
- package/dist/molecules/jl-search.d.ts +71 -0
- package/dist/molecules/jl-search.js +210 -0
- package/dist/molecules/jl-segmented.css_raw.js +3 -0
- package/dist/molecules/jl-segmented.d.ts +65 -0
- package/dist/molecules/jl-segmented.js +187 -0
- package/dist/molecules/jl-stat.css_raw.js +3 -0
- package/dist/molecules/jl-stat.d.ts +55 -0
- package/dist/molecules/jl-stat.js +169 -0
- package/dist/molecules/jl-steps.css_raw.js +3 -0
- package/dist/molecules/jl-steps.d.ts +44 -0
- package/dist/molecules/jl-steps.js +118 -0
- package/dist/molecules/jl-tab-panel.css_raw.js +3 -0
- package/dist/molecules/jl-tab-panel.d.ts +35 -0
- package/dist/molecules/jl-tab-panel.js +35 -0
- package/dist/molecules/jl-tabs.css_raw.js +3 -0
- package/dist/molecules/jl-tabs.d.ts +51 -0
- package/dist/molecules/jl-tabs.js +198 -0
- package/dist/molecules/jl-tag-input.css_raw.js +3 -0
- package/dist/molecules/jl-tag-input.d.ts +103 -0
- package/dist/molecules/jl-tag-input.js +429 -0
- package/dist/molecules/jl-timeline.css_raw.js +3 -0
- package/dist/molecules/jl-timeline.d.ts +28 -0
- package/dist/molecules/jl-timeline.js +81 -0
- package/dist/molecules/jl-toast.css_raw.js +3 -0
- package/dist/molecules/jl-toast.d.ts +75 -0
- package/dist/molecules/jl-toast.js +274 -0
- package/dist/molecules/jl-tooltip.css_raw.js +3 -0
- package/dist/molecules/jl-tooltip.d.ts +44 -0
- package/dist/molecules/jl-tooltip.js +160 -0
- package/dist/organisms/jl-command-palette.css_raw.js +3 -0
- package/dist/organisms/jl-command-palette.d.ts +60 -0
- package/dist/organisms/jl-command-palette.js +285 -0
- package/dist/organisms/jl-confirm.css_raw.js +3 -0
- package/dist/organisms/jl-confirm.d.ts +56 -0
- package/dist/organisms/jl-confirm.js +132 -0
- package/dist/organisms/jl-dialog.css_raw.js +3 -0
- package/dist/organisms/jl-dialog.d.ts +43 -0
- package/dist/organisms/jl-dialog.js +120 -0
- package/dist/organisms/jl-drawer.css_raw.js +3 -0
- package/dist/organisms/jl-drawer.d.ts +50 -0
- package/dist/organisms/jl-drawer.js +141 -0
- package/dist/organisms/jl-navbar.css_raw.js +3 -0
- package/dist/organisms/jl-navbar.d.ts +32 -0
- package/dist/organisms/jl-navbar.js +121 -0
- package/dist/organisms/jl-page-header.css_raw.js +3 -0
- package/dist/organisms/jl-page-header.d.ts +26 -0
- package/dist/organisms/jl-page-header.js +85 -0
- package/dist/organisms/jl-side-nav.css_raw.js +3 -0
- package/dist/organisms/jl-side-nav.d.ts +60 -0
- package/dist/organisms/jl-side-nav.js +269 -0
- package/dist/organisms/jl-table.css_raw.js +3 -0
- package/dist/organisms/jl-table.d.ts +109 -0
- package/dist/organisms/jl-table.js +318 -0
- package/dist/organisms/jl-toaster.css_raw.js +3 -0
- package/dist/organisms/jl-toaster.d.ts +48 -0
- package/dist/organisms/jl-toaster.js +142 -0
- package/dist/organisms/jl-tree.css_raw.js +3 -0
- package/dist/organisms/jl-tree.d.ts +59 -0
- package/dist/organisms/jl-tree.js +198 -0
- package/dist/styles/base.css_raw.js +3 -0
- package/dist/styles/control.css_raw.js +3 -0
- package/dist/styles/floating.css_raw.js +3 -0
- package/dist/styles/shared.d.ts +8 -0
- package/dist/styles/shared.js +14 -0
- package/dist/styles/tokens.css_raw.js +3 -0
- package/dist/templates/jl-app-shell.css_raw.js +3 -0
- package/dist/templates/jl-app-shell.d.ts +37 -0
- package/dist/templates/jl-app-shell.js +150 -0
- package/dist/templates/jl-split-view.css_raw.js +3 -0
- package/dist/templates/jl-split-view.d.ts +49 -0
- package/dist/templates/jl-split-view.js +149 -0
- package/dist/tokens.css +188 -0
- package/dist/types/calendar.types.d.ts +11 -0
- package/dist/types/files.types.d.ts +23 -0
- package/dist/types/floating.types.d.ts +13 -0
- package/dist/types/fuzzy.types.d.ts +10 -0
- package/dist/types/highlight.types.d.ts +6 -0
- package/dist/types/hotkey.types.d.ts +19 -0
- package/dist/types/jl-accordion.types.d.ts +2 -0
- package/dist/types/jl-avatar.types.d.ts +10 -0
- package/dist/types/jl-breadcrumb.types.d.ts +6 -0
- package/dist/types/jl-button.types.d.ts +3 -0
- package/dist/types/jl-card.types.d.ts +2 -0
- package/dist/types/jl-chip.types.d.ts +1 -0
- package/dist/types/jl-combobox.types.d.ts +8 -0
- package/dist/types/jl-command-palette.types.d.ts +22 -0
- package/dist/types/jl-confirm.types.d.ts +10 -0
- package/dist/types/jl-dialog.types.d.ts +1 -0
- package/dist/types/jl-divider.types.d.ts +2 -0
- package/dist/types/jl-drawer.types.d.ts +4 -0
- package/dist/types/jl-empty.types.d.ts +2 -0
- package/dist/types/jl-field.types.d.ts +2 -0
- package/dist/types/jl-input.types.d.ts +1 -0
- package/dist/types/jl-link.types.d.ts +2 -0
- package/dist/types/jl-menu.types.d.ts +22 -0
- package/dist/types/jl-navbar.types.d.ts +6 -0
- package/dist/types/jl-progress.types.d.ts +3 -0
- package/dist/types/jl-radio-group.types.d.ts +10 -0
- package/dist/types/jl-segmented.types.d.ts +7 -0
- package/dist/types/jl-select.types.d.ts +12 -0
- package/dist/types/jl-side-nav.types.d.ts +17 -0
- package/dist/types/jl-skeleton.types.d.ts +2 -0
- package/dist/types/jl-slider.types.d.ts +5 -0
- package/dist/types/jl-split-view.types.d.ts +2 -0
- package/dist/types/jl-stat.types.d.ts +2 -0
- package/dist/types/jl-steps.types.d.ts +8 -0
- package/dist/types/jl-switch.types.d.ts +1 -0
- package/dist/types/jl-table.types.d.ts +30 -0
- package/dist/types/jl-tabs.types.d.ts +2 -0
- package/dist/types/jl-timeline.types.d.ts +10 -0
- package/dist/types/jl-toast.types.d.ts +2 -0
- package/dist/types/jl-toaster.types.d.ts +23 -0
- package/dist/types/jl-tree.types.d.ts +26 -0
- package/dist/types/key-shortcut.types.d.ts +9 -0
- package/dist/types/keycaps.types.d.ts +7 -0
- package/dist/types/option-filter.types.d.ts +10 -0
- package/dist/types/options.types.d.ts +4 -0
- package/dist/types/pagination.types.d.ts +8 -0
- package/dist/types/roving-index.types.d.ts +2 -0
- package/dist/types/sparkline.types.d.ts +11 -0
- package/package.json +102 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 SyWare
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,134 @@
|
|
|
1
|
-
|
|
1
|
+
<img src="https://bioleyl.github.io/jlib/syware-logo.png" alt="SyWare" height="48">
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
# jlib
|
|
4
|
+
|
|
5
|
+
A component library on [Jadis](https://github.com/bioleyl/jadis) and native Web Components, organised in atomic
|
|
6
|
+
design: tags that work in any page, typed classes for JSX, form fields that submit like native ones, and a bundle
|
|
7
|
+
that holds only the components an app uses. Made by SyWare, for SyWare's own apps, and free for anyone to use.
|
|
8
|
+
|
|
9
|
+
The documentation site, https://bioleyl.github.io/jlib/ (or `npm run dev`), explains the library and shows every
|
|
10
|
+
component with a live playground, examples and its API.
|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install @syware/jlib @jadis/core
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Use
|
|
19
|
+
|
|
20
|
+
As HTML tags: define what the page writes (naming the classes keeps them in the bundle).
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
import { define, JlButton, JlInput } from '@syware/jlib';
|
|
24
|
+
|
|
25
|
+
define(JlButton, JlInput);
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
```html
|
|
29
|
+
<jl-input name="email" type="email" placeholder="you@example.com"></jl-input>
|
|
30
|
+
<jl-button variant="primary" label="Subscribe"></jl-button>
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
In JSX with Jadis (`"jsxImportSource": "@jadis/core"`), the classes are typed:
|
|
34
|
+
|
|
35
|
+
```tsx
|
|
36
|
+
import { JlButton } from '@syware/jlib';
|
|
37
|
+
|
|
38
|
+
<JlButton variant="primary" icon="plus" label="New project" />;
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
From code, inputs are change handlers and outputs typed events:
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
const button = new JlButton();
|
|
45
|
+
button.label.set('Save');
|
|
46
|
+
button.events.register('press', () => save());
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Components
|
|
50
|
+
|
|
51
|
+
- **Atoms**: avatar, badge, button, checkbox, chip, divider, icon, input, kbd, link, progress, progress ring, rating,
|
|
52
|
+
select, skeleton, slider, spinner, switch, textarea.
|
|
53
|
+
- **Molecules**: accordion, alert, avatar group, breadcrumb, calendar, card, code block, combobox, copy button, date
|
|
54
|
+
picker, empty state, field, file drop, list item, menu, number input, pagination, popover, radio group, search,
|
|
55
|
+
segmented control, stat, steps, tabs, tag input, timeline, toast, tooltip.
|
|
56
|
+
- **Organisms**: command palette, confirm, dialog, drawer, navbar, page header, side nav, table, toaster, tree.
|
|
57
|
+
- **Templates**: app shell, split view.
|
|
58
|
+
|
|
59
|
+
## Icons
|
|
60
|
+
|
|
61
|
+
Components draw their own icons with no setup. The names a page writes (`<jl-icon name="settings">`,
|
|
62
|
+
`icon="plus"` on a button) are registered once, so a bundle holds only the icons in use:
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
import { Coffee } from 'lucide';
|
|
66
|
+
import { COMMON_ICONS, registerIcons } from '@syware/jlib';
|
|
67
|
+
|
|
68
|
+
registerIcons({ coffee: Coffee }); // one by one, from lucide
|
|
69
|
+
registerIcons(COMMON_ICONS); // or the ~90 usual ones (about 5 kB)
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Theming
|
|
73
|
+
|
|
74
|
+
Every colour, radius and size is a CSS custom property (`--jl-*`), defined in the `jlib` cascade layer: a plain rule
|
|
75
|
+
of the page overrides it. Light and dark follow the system; `data-theme="light|dark"` on any element decides for that
|
|
76
|
+
part of the page.
|
|
77
|
+
|
|
78
|
+
```css
|
|
79
|
+
:root {
|
|
80
|
+
--jl-accent: #6d4ed8;
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Development
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
npm install
|
|
88
|
+
npm run dev # the documentation site, with hot reload
|
|
89
|
+
npm run check # generated files up to date, lint, types, unit tests
|
|
90
|
+
npm run test:e2e # builds the site and checks every page in a headless Chromium
|
|
91
|
+
npm run build # the library (dist/), the size report, the site (site/dist/)
|
|
92
|
+
npm run size # what each component adds to a bundle
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
`src/index.ts` and `src/all.ts` are generated from the component folders: run `npm run generate` after adding a
|
|
96
|
+
component. Conventions for contributors are in [CLAUDE.md](CLAUDE.md).
|
|
97
|
+
|
|
98
|
+
## Releasing
|
|
99
|
+
|
|
100
|
+
Pushing a version tag releases the package: the `Publish to npm` workflow checks and builds it, stages it on npm
|
|
101
|
+
through trusted publishing (no token; the package gets a provenance statement), then creates the GitHub release with
|
|
102
|
+
the package attached. The staged version becomes public once a maintainer approves it with their two-factor
|
|
103
|
+
authentication.
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
npm version patch
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
git push --follow-tags
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
`npm version` (or `minor`, `major`) bumps package.json and the lockfile, commits and tags `vX.Y.Z`. The workflow
|
|
114
|
+
refuses a tag that is not the version in package.json.
|
|
115
|
+
|
|
116
|
+
When the run is done (its summary page shows what was staged), approve the version:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
npm stage list @syware/jlib
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
npm stage approve <stage-id>
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Made by SyWare
|
|
127
|
+
|
|
128
|
+
jlib is the component library behind SyWare's apps, and it carries their look. SyWare makes it for its own products
|
|
129
|
+
and shares it: use it in yours, change it, ship it. The official SyWare logo is in `site/public/` as SVG:
|
|
130
|
+
`syware-logo.svg`, `syware-logo-dark.svg` for dark backgrounds, and `syware-mark.svg` for the mark alone.
|
|
131
|
+
|
|
132
|
+
## License
|
|
133
|
+
|
|
134
|
+
MIT, © SyWare: free to use, change and distribute. See [LICENSE](LICENSE).
|
package/dist/all.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './index';
|
package/dist/all.js
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { TOKEN_STYLES } from "./styles/shared.js";
|
|
2
|
+
import { adoptTokens } from "./lib/tokens.js";
|
|
3
|
+
import { JlElement } from "./base/jl-element.js";
|
|
4
|
+
import { JlFormControl } from "./base/jl-form-control.js";
|
|
5
|
+
import { clampedNumber, jsonOf, oneOf } from "./lib/attributes.js";
|
|
6
|
+
import { define } from "./lib/define.js";
|
|
7
|
+
import { PLACEMENTS, computePosition, followAnchor, placeFloating } from "./lib/floating.js";
|
|
8
|
+
import { COMMON_ICONS } from "./lib/icon-set.js";
|
|
9
|
+
import { hasIcon, iconElement, iconNames, registerIcons } from "./lib/icons.js";
|
|
10
|
+
import { CONTROL_SIZES, TONES, TONE_ICONS } from "./lib/options.js";
|
|
11
|
+
import { JlIcon } from "./atoms/jl-icon.js";
|
|
12
|
+
import { AVATAR_SHAPES, AVATAR_SIZES, AVATAR_STATUSES, JlAvatar } from "./atoms/jl-avatar.js";
|
|
13
|
+
import { JlBadge } from "./atoms/jl-badge.js";
|
|
14
|
+
import { JlSpinner } from "./atoms/jl-spinner.js";
|
|
15
|
+
import { BUTTON_TYPES, BUTTON_VARIANTS, JlButton } from "./atoms/jl-button.js";
|
|
16
|
+
import { JlCheckbox } from "./atoms/jl-checkbox.js";
|
|
17
|
+
import { CHIP_SIZES, JlChip } from "./atoms/jl-chip.js";
|
|
18
|
+
import { DIVIDER_ALIGNS, JlDivider } from "./atoms/jl-divider.js";
|
|
19
|
+
import { INPUT_TYPES, JlInput } from "./atoms/jl-input.js";
|
|
20
|
+
import { JlKbd } from "./atoms/jl-kbd.js";
|
|
21
|
+
import { JlLink, LINK_VARIANTS } from "./atoms/jl-link.js";
|
|
22
|
+
import { JlProgress, PROGRESS_SIZES, PROGRESS_TONES } from "./atoms/jl-progress.js";
|
|
23
|
+
import { JlProgressRing } from "./atoms/jl-progress-ring.js";
|
|
24
|
+
import { JlRating } from "./atoms/jl-rating.js";
|
|
25
|
+
import { JlSelect } from "./atoms/jl-select.js";
|
|
26
|
+
import { JlSkeleton, SKELETON_SHAPES } from "./atoms/jl-skeleton.js";
|
|
27
|
+
import { JlSlider } from "./atoms/jl-slider.js";
|
|
28
|
+
import { JlSwitch, SWITCH_SIZES } from "./atoms/jl-switch.js";
|
|
29
|
+
import { JlTextarea } from "./atoms/jl-textarea.js";
|
|
30
|
+
import { JlAccordionItem } from "./molecules/jl-accordion-item.js";
|
|
31
|
+
import { ACCORDION_VARIANTS, JlAccordion } from "./molecules/jl-accordion.js";
|
|
32
|
+
import { JlAlert } from "./molecules/jl-alert.js";
|
|
33
|
+
import { JlAvatarGroup } from "./molecules/jl-avatar-group.js";
|
|
34
|
+
import { JlBreadcrumb } from "./molecules/jl-breadcrumb.js";
|
|
35
|
+
import { JlCalendar } from "./molecules/jl-calendar.js";
|
|
36
|
+
import { CARD_PADDINGS, JlCard } from "./molecules/jl-card.js";
|
|
37
|
+
import { JlCopyButton } from "./molecules/jl-copy-button.js";
|
|
38
|
+
import { CODE_LANGUAGES, JlCodeBlock } from "./molecules/jl-code-block.js";
|
|
39
|
+
import { JlCombobox } from "./molecules/jl-combobox.js";
|
|
40
|
+
import { JlDatePicker } from "./molecules/jl-date-picker.js";
|
|
41
|
+
import { EMPTY_SIZES, JlEmpty } from "./molecules/jl-empty.js";
|
|
42
|
+
import { FIELD_ORIENTATIONS, JlField } from "./molecules/jl-field.js";
|
|
43
|
+
import { JlFileDrop } from "./molecules/jl-file-drop.js";
|
|
44
|
+
import { JlListItem } from "./molecules/jl-list-item.js";
|
|
45
|
+
import { JlMenu } from "./molecules/jl-menu.js";
|
|
46
|
+
import { JlNumberInput } from "./molecules/jl-number-input.js";
|
|
47
|
+
import { JlPagination } from "./molecules/jl-pagination.js";
|
|
48
|
+
import { JlPopover } from "./molecules/jl-popover.js";
|
|
49
|
+
import { JlRadioGroup, RADIO_GROUP_ORIENTATIONS, RADIO_GROUP_VARIANTS } from "./molecules/jl-radio-group.js";
|
|
50
|
+
import { JlSearch } from "./molecules/jl-search.js";
|
|
51
|
+
import { JlSegmented } from "./molecules/jl-segmented.js";
|
|
52
|
+
import { JlStat, STAT_TRENDS } from "./molecules/jl-stat.js";
|
|
53
|
+
import { JlSteps, STEPS_ORIENTATIONS } from "./molecules/jl-steps.js";
|
|
54
|
+
import { JlTabPanel } from "./molecules/jl-tab-panel.js";
|
|
55
|
+
import { JlTabs, TAB_VARIANTS } from "./molecules/jl-tabs.js";
|
|
56
|
+
import { JlTagInput } from "./molecules/jl-tag-input.js";
|
|
57
|
+
import { JlTimeline } from "./molecules/jl-timeline.js";
|
|
58
|
+
import { JlToast, TOAST_TONES } from "./molecules/jl-toast.js";
|
|
59
|
+
import { JlTooltip } from "./molecules/jl-tooltip.js";
|
|
60
|
+
import { JlCommandPalette } from "./organisms/jl-command-palette.js";
|
|
61
|
+
import { DIALOG_SIZES, JlDialog } from "./organisms/jl-dialog.js";
|
|
62
|
+
import { CONFIRM_TONES, JlConfirm, confirmDialog } from "./organisms/jl-confirm.js";
|
|
63
|
+
import { DRAWER_PLACEMENTS, DRAWER_SIZES, JlDrawer } from "./organisms/jl-drawer.js";
|
|
64
|
+
import { JlNavbar } from "./organisms/jl-navbar.js";
|
|
65
|
+
import { JlPageHeader } from "./organisms/jl-page-header.js";
|
|
66
|
+
import { JlSideNav } from "./organisms/jl-side-nav.js";
|
|
67
|
+
import { JlTable, TABLE_SORT_DIRECTIONS } from "./organisms/jl-table.js";
|
|
68
|
+
import { JlToaster, TOASTER_PLACEMENTS, toast } from "./organisms/jl-toaster.js";
|
|
69
|
+
import { JlTree } from "./organisms/jl-tree.js";
|
|
70
|
+
import { JlAppShell } from "./templates/jl-app-shell.js";
|
|
71
|
+
import { JlSplitView, SPLIT_ORIENTATIONS } from "./templates/jl-split-view.js";
|
|
72
|
+
// src/all.ts
|
|
73
|
+
registerIcons(COMMON_ICONS);
|
|
74
|
+
define(JlAccordion, JlAccordionItem, JlAlert, JlAppShell, JlAvatar, JlAvatarGroup, JlBadge, JlBreadcrumb, JlButton, JlCalendar, JlCard, JlCheckbox, JlChip, JlCodeBlock, JlCombobox, JlCommandPalette, JlConfirm, JlCopyButton, JlDatePicker, JlDialog, JlDivider, JlDrawer, JlEmpty, JlField, JlFileDrop, JlIcon, JlInput, JlKbd, JlLink, JlListItem, JlMenu, JlNavbar, JlNumberInput, JlPageHeader, JlPagination, JlPopover, JlProgress, JlProgressRing, JlRadioGroup, JlRating, JlSearch, JlSegmented, JlSelect, JlSideNav, JlSkeleton, JlSlider, JlSpinner, JlSplitView, JlStat, JlSteps, JlSwitch, JlTable, JlTabPanel, JlTabs, JlTagInput, JlTextarea, JlTimeline, JlToast, JlToaster, JlTooltip, JlTree);
|
|
75
|
+
export { ACCORDION_VARIANTS, AVATAR_SHAPES, AVATAR_SIZES, AVATAR_STATUSES, BUTTON_TYPES, BUTTON_VARIANTS, CARD_PADDINGS, CHIP_SIZES, CODE_LANGUAGES, COMMON_ICONS, CONFIRM_TONES, CONTROL_SIZES, DIALOG_SIZES, DIVIDER_ALIGNS, DRAWER_PLACEMENTS, DRAWER_SIZES, EMPTY_SIZES, FIELD_ORIENTATIONS, INPUT_TYPES, JlAccordion, JlAccordionItem, JlAlert, JlAppShell, JlAvatar, JlAvatarGroup, JlBadge, JlBreadcrumb, JlButton, JlCalendar, JlCard, JlCheckbox, JlChip, JlCodeBlock, JlCombobox, JlCommandPalette, JlConfirm, JlCopyButton, JlDatePicker, JlDialog, JlDivider, JlDrawer, JlElement, JlEmpty, JlField, JlFileDrop, JlFormControl, JlIcon, JlInput, JlKbd, JlLink, JlListItem, JlMenu, JlNavbar, JlNumberInput, JlPageHeader, JlPagination, JlPopover, JlProgress, JlProgressRing, JlRadioGroup, JlRating, JlSearch, JlSegmented, JlSelect, JlSideNav, JlSkeleton, JlSlider, JlSpinner, JlSplitView, JlStat, JlSteps, JlSwitch, JlTabPanel, JlTable, JlTabs, JlTagInput, JlTextarea, JlTimeline, JlToast, JlToaster, JlTooltip, JlTree, LINK_VARIANTS, PLACEMENTS, PROGRESS_SIZES, PROGRESS_TONES, RADIO_GROUP_ORIENTATIONS, RADIO_GROUP_VARIANTS, SKELETON_SHAPES, SPLIT_ORIENTATIONS, STAT_TRENDS, STEPS_ORIENTATIONS, SWITCH_SIZES, TABLE_SORT_DIRECTIONS, TAB_VARIANTS, TOASTER_PLACEMENTS, TOAST_TONES, TOKEN_STYLES, TONES, TONE_ICONS, adoptTokens, clampedNumber, computePosition, confirmDialog, define, followAnchor, hasIcon, iconElement, iconNames, jsonOf, oneOf, placeFloating, registerIcons, toast };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
// src/atoms/jl-avatar.css?raw
|
|
2
|
+
var jl_avatar_default = ":host {\n display: inline-flex;\n flex: none;\n vertical-align: middle;\n --size: 32px;\n --ring: 0px;\n --ring-color: var(--jl-surface);\n --fg: var(--jl-text-2);\n --bg: var(--jl-surface-3);\n}\n\n:host([size=\"sm\"]) {\n --size: 24px;\n}\n\n:host([size=\"lg\"]) {\n --size: 40px;\n}\n\n:host([size=\"xl\"]) {\n --size: 56px;\n}\n\n:host([tone=\"accent\"]) {\n --fg: var(--jl-accent);\n --bg: var(--jl-accent-soft);\n}\n\n:host([tone=\"ok\"]) {\n --fg: var(--jl-ok);\n --bg: var(--jl-ok-soft);\n}\n\n:host([tone=\"warn\"]) {\n --fg: var(--jl-warn);\n --bg: var(--jl-warn-soft);\n}\n\n:host([tone=\"danger\"]) {\n --fg: var(--jl-danger);\n --bg: var(--jl-danger-soft);\n}\n\n.avatar {\n position: relative;\n display: inline-flex;\n width: var(--size);\n height: var(--size);\n}\n\n.face {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n overflow: hidden;\n border-radius: 50%;\n background: var(--bg);\n color: var(--fg);\n font-size: calc(var(--size) * 0.38);\n font-weight: 700;\n letter-spacing: 0.01em;\n line-height: 1;\n white-space: nowrap;\n box-shadow: 0 0 0 var(--ring) var(--ring-color);\n user-select: none;\n}\n\n:host([shape=\"square\"]) .face {\n border-radius: calc(var(--size) * 0.25);\n}\n\n:host([has-image]) .face {\n background: var(--jl-surface-3);\n}\n\nimg {\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n.status {\n position: absolute;\n right: 0;\n bottom: 0;\n width: max(7px, calc(var(--size) * 0.26));\n height: max(7px, calc(var(--size) * 0.26));\n border-radius: 50%;\n background: var(--jl-faint);\n box-shadow: 0 0 0 2px var(--ring-color);\n}\n\n:host([shape=\"square\"]) .status {\n right: -2px;\n bottom: -2px;\n}\n\n:host([status=\"online\"]) .status {\n background: var(--jl-ok);\n}\n\n:host([status=\"busy\"]) .status {\n background: var(--jl-danger);\n}\n\n:host([status=\"away\"]) .status {\n background: var(--jl-warn);\n}\n";
|
|
3
|
+
export { jl_avatar_default as default };
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { JlElement } from '../base/jl-element';
|
|
2
|
+
import type { AvatarShape, AvatarSize, AvatarStatus } from '../types/jl-avatar.types';
|
|
3
|
+
export declare const AVATAR_SIZES: readonly AvatarSize[];
|
|
4
|
+
export declare const AVATAR_SHAPES: readonly AvatarShape[];
|
|
5
|
+
export declare const AVATAR_STATUSES: readonly AvatarStatus[];
|
|
6
|
+
/**
|
|
7
|
+
* A person or a team: their picture, or their initials on a colour the name always picks. A `status` dot tells
|
|
8
|
+
* their presence. Slotted content (an icon, a count) replaces the initials.
|
|
9
|
+
*/
|
|
10
|
+
export declare class JlAvatar extends JlElement {
|
|
11
|
+
static readonly selector = "jl-avatar";
|
|
12
|
+
/** The person's name: their initials, the background colour, and what screen readers say. */
|
|
13
|
+
readonly name: Readonly<Readonly<{
|
|
14
|
+
get(): string;
|
|
15
|
+
set(setter: string | ((prevState: string) => string)): void;
|
|
16
|
+
}>>;
|
|
17
|
+
/** A picture; the initials show while it loads and when it cannot. */
|
|
18
|
+
readonly src: Readonly<Readonly<{
|
|
19
|
+
get(): string;
|
|
20
|
+
set(setter: string | ((prevState: string) => string)): void;
|
|
21
|
+
}>>;
|
|
22
|
+
readonly size: Readonly<Readonly<{
|
|
23
|
+
get(): AvatarSize;
|
|
24
|
+
set(setter: ((prevState: AvatarSize) => AvatarSize) | AvatarSize): void;
|
|
25
|
+
}>>;
|
|
26
|
+
readonly shape: Readonly<Readonly<{
|
|
27
|
+
get(): AvatarShape;
|
|
28
|
+
set(setter: ((prevState: AvatarShape) => AvatarShape) | AvatarShape): void;
|
|
29
|
+
}>>;
|
|
30
|
+
readonly status: Readonly<Readonly<{
|
|
31
|
+
get(): "" | AvatarStatus;
|
|
32
|
+
set(setter: "" | ((prevState: "" | AvatarStatus) => "" | AvatarStatus) | AvatarStatus): void;
|
|
33
|
+
}>>;
|
|
34
|
+
/** What screen readers say, when it should differ from the name. */
|
|
35
|
+
readonly label: Readonly<Readonly<{
|
|
36
|
+
get(): string;
|
|
37
|
+
set(setter: string | ((prevState: string) => string)): void;
|
|
38
|
+
}>>;
|
|
39
|
+
private readonly _image;
|
|
40
|
+
private readonly _refs;
|
|
41
|
+
templateHtml(): Node;
|
|
42
|
+
templateCss(): string;
|
|
43
|
+
onConnect(): void;
|
|
44
|
+
private loadImage;
|
|
45
|
+
private settleImage;
|
|
46
|
+
private renderName;
|
|
47
|
+
/** The picture once it loaded; otherwise slotted content, the initials, or a person icon, in that order. */
|
|
48
|
+
private renderFace;
|
|
49
|
+
private renderSize;
|
|
50
|
+
private renderStatus;
|
|
51
|
+
private renderLabel;
|
|
52
|
+
}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { BASE_STYLES } from "../styles/shared.js";
|
|
2
|
+
import { JlElement } from "../base/jl-element.js";
|
|
3
|
+
import { oneOf } from "../lib/attributes.js";
|
|
4
|
+
import { registerIcons } from "../lib/icons.js";
|
|
5
|
+
import { initialsOf, pickStable } from "../lib/avatar.js";
|
|
6
|
+
import { setOrRemove } from "../lib/dom.js";
|
|
7
|
+
import { hasSlotted } from "../lib/slots.js";
|
|
8
|
+
import jl_avatar_default from "./jl-avatar.css_raw.js";
|
|
9
|
+
import { JlIcon } from "./jl-icon.js";
|
|
10
|
+
import { css } from "@jadis/core";
|
|
11
|
+
import { User } from "lucide";
|
|
12
|
+
import { jsx, jsxs } from "@jadis/core/jsx-runtime";
|
|
13
|
+
// src/atoms/jl-avatar.tsx
|
|
14
|
+
registerIcons({ user: User });
|
|
15
|
+
var AVATAR_SIZES = [
|
|
16
|
+
"md",
|
|
17
|
+
"sm",
|
|
18
|
+
"lg",
|
|
19
|
+
"xl"
|
|
20
|
+
];
|
|
21
|
+
var AVATAR_SHAPES = ["circle", "square"];
|
|
22
|
+
var AVATAR_STATUSES = [
|
|
23
|
+
"online",
|
|
24
|
+
"busy",
|
|
25
|
+
"away",
|
|
26
|
+
"offline"
|
|
27
|
+
];
|
|
28
|
+
/** The soft tones a name picks its background from; an avatar without a name is neutral. */
|
|
29
|
+
var NAME_TONES = [
|
|
30
|
+
"accent",
|
|
31
|
+
"ok",
|
|
32
|
+
"warn",
|
|
33
|
+
"danger",
|
|
34
|
+
"neutral"
|
|
35
|
+
];
|
|
36
|
+
var NO_NAME_TONE = "neutral";
|
|
37
|
+
var STATUS_LABELS = {
|
|
38
|
+
away: "away",
|
|
39
|
+
busy: "busy",
|
|
40
|
+
offline: "offline",
|
|
41
|
+
online: "online"
|
|
42
|
+
};
|
|
43
|
+
var ICON_SIZES = {
|
|
44
|
+
lg: 20,
|
|
45
|
+
md: 16,
|
|
46
|
+
sm: 13,
|
|
47
|
+
xl: 28
|
|
48
|
+
};
|
|
49
|
+
var FALLBACK_ICON = "user";
|
|
50
|
+
/**
|
|
51
|
+
* A person or a team: their picture, or their initials on a colour the name always picks. A `status` dot tells
|
|
52
|
+
* their presence. Slotted content (an icon, a count) replaces the initials.
|
|
53
|
+
*/
|
|
54
|
+
var JlAvatar = class extends JlElement {
|
|
55
|
+
static selector = "jl-avatar";
|
|
56
|
+
/** The person's name: their initials, the background colour, and what screen readers say. */
|
|
57
|
+
name = this.useChange("", () => this.renderName(), { attribute: "name" });
|
|
58
|
+
/** A picture; the initials show while it loads and when it cannot. */
|
|
59
|
+
src = this.useChange("", (value) => this.loadImage(value), { attribute: "src" });
|
|
60
|
+
size = this.useChange("md", (value) => this.renderSize(value), {
|
|
61
|
+
attribute: "size",
|
|
62
|
+
parse: oneOf(AVATAR_SIZES, "md")
|
|
63
|
+
});
|
|
64
|
+
shape = this.useChange("circle", (value) => this.reflect("shape", value), {
|
|
65
|
+
attribute: "shape",
|
|
66
|
+
parse: oneOf(AVATAR_SHAPES, "circle")
|
|
67
|
+
});
|
|
68
|
+
status = this.useChange("", (value) => this.renderStatus(value), {
|
|
69
|
+
attribute: "status",
|
|
70
|
+
parse: oneOf(["", ...AVATAR_STATUSES], "")
|
|
71
|
+
});
|
|
72
|
+
/** What screen readers say, when it should differ from the name. */
|
|
73
|
+
label = this.useChange("", () => this.renderLabel(), { attribute: "label" });
|
|
74
|
+
_image = { loaded: false };
|
|
75
|
+
_refs = this.useRefs((ref) => ({
|
|
76
|
+
avatar: ref(".avatar"),
|
|
77
|
+
icon: ref(".fallback"),
|
|
78
|
+
image: ref("img"),
|
|
79
|
+
initials: ref(".initials"),
|
|
80
|
+
slot: ref("slot"),
|
|
81
|
+
status: ref(".status")
|
|
82
|
+
}));
|
|
83
|
+
templateHtml() {
|
|
84
|
+
return /* @__PURE__ */ jsxs("span", {
|
|
85
|
+
class: "avatar",
|
|
86
|
+
role: "img",
|
|
87
|
+
attrs: { part: "base" },
|
|
88
|
+
children: [/* @__PURE__ */ jsxs("span", {
|
|
89
|
+
class: "face",
|
|
90
|
+
children: [
|
|
91
|
+
/* @__PURE__ */ jsx("img", {
|
|
92
|
+
alt: "",
|
|
93
|
+
hidden: true,
|
|
94
|
+
onLoad: () => this.settleImage(true),
|
|
95
|
+
onError: () => this.settleImage(false)
|
|
96
|
+
}),
|
|
97
|
+
/* @__PURE__ */ jsx("span", {
|
|
98
|
+
class: "initials",
|
|
99
|
+
"aria-hidden": "true"
|
|
100
|
+
}),
|
|
101
|
+
/* @__PURE__ */ jsx(JlIcon, {
|
|
102
|
+
class: "fallback",
|
|
103
|
+
name: FALLBACK_ICON,
|
|
104
|
+
hidden: true
|
|
105
|
+
}),
|
|
106
|
+
/* @__PURE__ */ jsx("slot", {})
|
|
107
|
+
]
|
|
108
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
109
|
+
class: "status",
|
|
110
|
+
hidden: true
|
|
111
|
+
})]
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
templateCss() {
|
|
115
|
+
return css`${BASE_STYLES}${jl_avatar_default}`;
|
|
116
|
+
}
|
|
117
|
+
onConnect() {
|
|
118
|
+
this.renderFace();
|
|
119
|
+
this.on(this._refs.slot, "slotchange", () => this.renderFace());
|
|
120
|
+
}
|
|
121
|
+
loadImage(src) {
|
|
122
|
+
this._image.loaded = false;
|
|
123
|
+
setOrRemove(this._refs.image, "src", src);
|
|
124
|
+
this.renderFace();
|
|
125
|
+
}
|
|
126
|
+
settleImage(loaded) {
|
|
127
|
+
this._image.loaded = loaded && this.src.get() !== "";
|
|
128
|
+
this.renderFace();
|
|
129
|
+
}
|
|
130
|
+
renderName() {
|
|
131
|
+
const name = this.name.get();
|
|
132
|
+
this._refs.initials.textContent = initialsOf(name);
|
|
133
|
+
this.reflect("tone", name.trim() === "" ? NO_NAME_TONE : pickStable(name.trim(), NAME_TONES));
|
|
134
|
+
this.renderFace();
|
|
135
|
+
this.renderLabel();
|
|
136
|
+
}
|
|
137
|
+
/** The picture once it loaded; otherwise slotted content, the initials, or a person icon, in that order. */
|
|
138
|
+
renderFace() {
|
|
139
|
+
const image = this._image.loaded;
|
|
140
|
+
const custom = hasSlotted(this._refs.slot);
|
|
141
|
+
const hasInitials = this._refs.initials.textContent !== "";
|
|
142
|
+
this._refs.image.hidden = !image;
|
|
143
|
+
this._refs.slot.hidden = image;
|
|
144
|
+
this._refs.initials.hidden = image || custom || !hasInitials;
|
|
145
|
+
this._refs.icon.hidden = image || custom || hasInitials;
|
|
146
|
+
this.reflect("has-image", image);
|
|
147
|
+
}
|
|
148
|
+
renderSize(size) {
|
|
149
|
+
this.reflect("size", size);
|
|
150
|
+
this._refs.icon.size.set(ICON_SIZES[size]);
|
|
151
|
+
}
|
|
152
|
+
renderStatus(status) {
|
|
153
|
+
this._refs.status.hidden = status === "";
|
|
154
|
+
this.reflect("status", status);
|
|
155
|
+
this.renderLabel();
|
|
156
|
+
}
|
|
157
|
+
renderLabel() {
|
|
158
|
+
const name = this.label.get() || this.name.get().trim();
|
|
159
|
+
const status = this.status.get();
|
|
160
|
+
const spoken = status === "" ? name : [name, STATUS_LABELS[status]].filter((part) => part !== "").join(", ");
|
|
161
|
+
const avatar = this._refs.avatar;
|
|
162
|
+
setOrRemove(avatar, "aria-label", spoken);
|
|
163
|
+
avatar.setAttribute("role", spoken === "" ? "presentation" : "img");
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
JlAvatar.register();
|
|
167
|
+
export { AVATAR_SHAPES, AVATAR_SIZES, AVATAR_STATUSES, JlAvatar };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
// src/atoms/jl-badge.css?raw
|
|
2
|
+
var jl_badge_default = ":host {\n display: inline-flex;\n vertical-align: middle;\n --fg: var(--jl-text-2);\n --bg: var(--jl-surface-3);\n}\n\n:host([tone=\"accent\"]) {\n --fg: var(--jl-accent);\n --bg: var(--jl-accent-soft);\n}\n\n:host([tone=\"ok\"]) {\n --fg: var(--jl-ok);\n --bg: var(--jl-ok-soft);\n}\n\n:host([tone=\"warn\"]) {\n --fg: var(--jl-warn);\n --bg: var(--jl-warn-soft);\n}\n\n:host([tone=\"danger\"]) {\n --fg: var(--jl-danger);\n --bg: var(--jl-danger-soft);\n}\n\n:host([tone=\"info\"]) {\n --fg: var(--jl-info);\n --bg: var(--jl-info-soft);\n}\n\n.badge {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n height: 22px;\n padding: 0 8px;\n border-radius: var(--jl-radius-pill);\n background: var(--bg);\n color: var(--fg);\n font-size: var(--jl-font-xs);\n font-weight: 600;\n line-height: 1;\n white-space: nowrap;\n}\n\n:host([solid]) .badge {\n background: var(--fg);\n color: var(--jl-surface);\n}\n\n:host([tone=\"neutral\"][solid]) .badge {\n background: var(--jl-text);\n}\n\n.label:empty {\n display: none;\n}\n\n.dot {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: currentColor;\n box-shadow: 0 0 0 3px color-mix(in srgb, currentColor 18%, transparent);\n}\n";
|
|
3
|
+
export { jl_badge_default as default };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { JlElement } from '../base/jl-element';
|
|
2
|
+
import type { Tone } from '../types/options.types';
|
|
3
|
+
/** A short status, coloured by its tone: "Active", "3 new", "Failed". A `dot` marks a live state. */
|
|
4
|
+
export declare class JlBadge extends JlElement {
|
|
5
|
+
static readonly selector = "jl-badge";
|
|
6
|
+
readonly label: Readonly<Readonly<{
|
|
7
|
+
get(): string;
|
|
8
|
+
set(setter: string | ((prevState: string) => string)): void;
|
|
9
|
+
}>>;
|
|
10
|
+
readonly tone: Readonly<Readonly<{
|
|
11
|
+
get(): Tone;
|
|
12
|
+
set(setter: ((prevState: Tone) => Tone) | Tone): void;
|
|
13
|
+
}>>;
|
|
14
|
+
readonly icon: Readonly<Readonly<{
|
|
15
|
+
get(): string;
|
|
16
|
+
set(setter: string | ((prevState: string) => string)): void;
|
|
17
|
+
}>>;
|
|
18
|
+
readonly dot: Readonly<Readonly<{
|
|
19
|
+
get(): boolean;
|
|
20
|
+
set(setter: boolean | ((prevState: boolean) => boolean)): void;
|
|
21
|
+
}>>;
|
|
22
|
+
/** Filled with the tone's colour, for what must stand out. */
|
|
23
|
+
readonly solid: Readonly<Readonly<{
|
|
24
|
+
get(): boolean;
|
|
25
|
+
set(setter: boolean | ((prevState: boolean) => boolean)): void;
|
|
26
|
+
}>>;
|
|
27
|
+
private readonly _refs;
|
|
28
|
+
templateHtml(): Node;
|
|
29
|
+
templateCss(): string;
|
|
30
|
+
/** An icon wins over the dot: a badge shows one marker at most. */
|
|
31
|
+
private renderMarker;
|
|
32
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { BASE_STYLES } from "../styles/shared.js";
|
|
2
|
+
import { JlElement } from "../base/jl-element.js";
|
|
3
|
+
import { oneOf } from "../lib/attributes.js";
|
|
4
|
+
import { TONES } from "../lib/options.js";
|
|
5
|
+
import { JlIcon } from "./jl-icon.js";
|
|
6
|
+
import jl_badge_default from "./jl-badge.css_raw.js";
|
|
7
|
+
import { css } from "@jadis/core";
|
|
8
|
+
import { jsx, jsxs } from "@jadis/core/jsx-runtime";
|
|
9
|
+
// src/atoms/jl-badge.tsx
|
|
10
|
+
var ICON_SIZE = 13;
|
|
11
|
+
/** A short status, coloured by its tone: "Active", "3 new", "Failed". A `dot` marks a live state. */
|
|
12
|
+
var JlBadge = class extends JlElement {
|
|
13
|
+
static selector = "jl-badge";
|
|
14
|
+
label = this.useChange("", (value) => {
|
|
15
|
+
this._refs.label.textContent = value;
|
|
16
|
+
}, { attribute: "label" });
|
|
17
|
+
tone = this.useChange("neutral", (value) => this.reflect("tone", value), {
|
|
18
|
+
attribute: "tone",
|
|
19
|
+
parse: oneOf(TONES, "neutral")
|
|
20
|
+
});
|
|
21
|
+
icon = this.useChange("", () => this.renderMarker(), { attribute: "icon" });
|
|
22
|
+
dot = this.useChange(false, () => this.renderMarker(), { attribute: "dot" });
|
|
23
|
+
/** Filled with the tone's colour, for what must stand out. */
|
|
24
|
+
solid = this.useChange(false, (value) => this.reflect("solid", value), { attribute: "solid" });
|
|
25
|
+
_refs = this.useRefs((ref) => ({
|
|
26
|
+
dot: ref(".dot"),
|
|
27
|
+
icon: ref("jl-icon"),
|
|
28
|
+
label: ref(".label")
|
|
29
|
+
}));
|
|
30
|
+
templateHtml() {
|
|
31
|
+
return /* @__PURE__ */ jsxs("span", {
|
|
32
|
+
class: "badge",
|
|
33
|
+
attrs: { part: "base" },
|
|
34
|
+
children: [
|
|
35
|
+
/* @__PURE__ */ jsx("span", {
|
|
36
|
+
class: "dot",
|
|
37
|
+
hidden: true
|
|
38
|
+
}),
|
|
39
|
+
/* @__PURE__ */ jsx(JlIcon, {
|
|
40
|
+
size: ICON_SIZE,
|
|
41
|
+
hidden: true
|
|
42
|
+
}),
|
|
43
|
+
/* @__PURE__ */ jsx("span", { class: "label" }),
|
|
44
|
+
/* @__PURE__ */ jsx("slot", {})
|
|
45
|
+
]
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
templateCss() {
|
|
49
|
+
return css`${BASE_STYLES}${jl_badge_default}`;
|
|
50
|
+
}
|
|
51
|
+
/** An icon wins over the dot: a badge shows one marker at most. */
|
|
52
|
+
renderMarker() {
|
|
53
|
+
const icon = this.icon.get();
|
|
54
|
+
this._refs.icon.name.set(icon);
|
|
55
|
+
this._refs.icon.hidden = icon === "";
|
|
56
|
+
this._refs.dot.hidden = icon !== "" || !this.dot.get();
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
JlBadge.register();
|
|
60
|
+
export { JlBadge };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
// src/atoms/jl-button.css?raw
|
|
2
|
+
var jl_button_default = ":host {\n display: inline-flex;\n vertical-align: middle;\n --height: var(--jl-control-md);\n --pad: 14px;\n --font-size: var(--jl-font-md);\n --radius: var(--jl-radius-sm);\n}\n\n:host([size=\"sm\"]) {\n --height: var(--jl-control-sm);\n --pad: 11px;\n --font-size: var(--jl-font-xs);\n}\n\n:host([size=\"lg\"]) {\n --height: var(--jl-control-lg);\n --pad: 18px;\n --font-size: 15px;\n --radius: var(--jl-radius);\n}\n\n:host([block]) {\n display: flex;\n}\n\nbutton {\n display: inline-flex;\n flex: 1;\n align-items: center;\n justify-content: center;\n gap: 8px;\n height: var(--height);\n padding: 0 var(--pad);\n border: 1px solid var(--jl-line-strong);\n border-radius: var(--radius);\n background: var(--jl-surface);\n color: var(--jl-text);\n font-size: var(--font-size);\n font-weight: 600;\n line-height: 1;\n white-space: nowrap;\n cursor: pointer;\n transition:\n background var(--jl-fast) var(--jl-ease),\n border-color var(--jl-fast) var(--jl-ease),\n color var(--jl-fast) var(--jl-ease);\n}\n\n:host([icon-only]) button {\n width: var(--height);\n padding: 0;\n}\n\nbutton:hover {\n background: var(--jl-surface-2);\n}\n\nbutton:active {\n background: var(--jl-surface-3);\n}\n\n:host([variant=\"primary\"]) button {\n border-color: transparent;\n background: var(--jl-accent);\n color: var(--jl-on-accent);\n}\n\n:host([variant=\"primary\"]) button:hover {\n background: var(--jl-accent-strong);\n}\n\n:host([variant=\"ghost\"]) button {\n border-color: transparent;\n background: transparent;\n color: var(--jl-accent);\n}\n\n:host([variant=\"ghost\"]) button:hover {\n background: var(--jl-accent-soft);\n}\n\n:host([variant=\"danger\"]) button {\n border-color: transparent;\n background: var(--jl-danger);\n color: var(--jl-on-danger);\n}\n\n:host([variant=\"danger\"]) button:hover {\n background: color-mix(in srgb, var(--jl-danger) 86%, var(--jl-text));\n}\n\n:host([loading]) button {\n cursor: progress;\n}\n\nbutton:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n";
|
|
3
|
+
export { jl_button_default as default };
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { JlElement } from '../base/jl-element';
|
|
2
|
+
import type { ButtonType, ButtonVariant } from '../types/jl-button.types';
|
|
3
|
+
import type { ControlSize } from '../types/options.types';
|
|
4
|
+
export declare const BUTTON_VARIANTS: readonly ButtonVariant[];
|
|
5
|
+
export declare const BUTTON_TYPES: readonly ButtonType[];
|
|
6
|
+
/**
|
|
7
|
+
* A button. Its text is the `label` (or the slotted content); with only an `icon`, its `hint` names it.
|
|
8
|
+
* Listen to `press`: it fires only while the button can be pressed. `type="submit"` submits the surrounding form.
|
|
9
|
+
*/
|
|
10
|
+
export declare class JlButton extends JlElement {
|
|
11
|
+
static readonly selector = "jl-button";
|
|
12
|
+
static readonly formAssociated = true;
|
|
13
|
+
readonly events: Readonly<import("@jadis/core").UseEventsHandler<{
|
|
14
|
+
press: undefined;
|
|
15
|
+
}>>;
|
|
16
|
+
readonly label: Readonly<Readonly<{
|
|
17
|
+
get(): string;
|
|
18
|
+
set(setter: string | ((prevState: string) => string)): void;
|
|
19
|
+
}>>;
|
|
20
|
+
readonly icon: Readonly<Readonly<{
|
|
21
|
+
get(): string;
|
|
22
|
+
set(setter: string | ((prevState: string) => string)): void;
|
|
23
|
+
}>>;
|
|
24
|
+
readonly iconEnd: Readonly<Readonly<{
|
|
25
|
+
get(): string;
|
|
26
|
+
set(setter: string | ((prevState: string) => string)): void;
|
|
27
|
+
}>>;
|
|
28
|
+
readonly variant: Readonly<Readonly<{
|
|
29
|
+
get(): ButtonVariant;
|
|
30
|
+
set(setter: ((prevState: ButtonVariant) => ButtonVariant) | ButtonVariant): void;
|
|
31
|
+
}>>;
|
|
32
|
+
readonly size: Readonly<Readonly<{
|
|
33
|
+
get(): ControlSize;
|
|
34
|
+
set(setter: ((prevState: ControlSize) => ControlSize) | ControlSize): void;
|
|
35
|
+
}>>;
|
|
36
|
+
readonly type: Readonly<Readonly<{
|
|
37
|
+
get(): ButtonType;
|
|
38
|
+
set(setter: ((prevState: ButtonType) => ButtonType) | ButtonType): void;
|
|
39
|
+
}>>;
|
|
40
|
+
readonly disabled: Readonly<Readonly<{
|
|
41
|
+
get(): boolean;
|
|
42
|
+
set(setter: boolean | ((prevState: boolean) => boolean)): void;
|
|
43
|
+
}>>;
|
|
44
|
+
/** Shows a spinner in place of the icon and ignores presses, while the work it started runs. */
|
|
45
|
+
readonly loading: Readonly<Readonly<{
|
|
46
|
+
get(): boolean;
|
|
47
|
+
set(setter: boolean | ((prevState: boolean) => boolean)): void;
|
|
48
|
+
}>>;
|
|
49
|
+
/** The tooltip; also the button's name for screen readers when it only has an icon. */
|
|
50
|
+
readonly hint: Readonly<Readonly<{
|
|
51
|
+
get(): string;
|
|
52
|
+
set(setter: string | ((prevState: string) => string)): void;
|
|
53
|
+
}>>;
|
|
54
|
+
/** Takes the whole width of its container. */
|
|
55
|
+
readonly block: Readonly<Readonly<{
|
|
56
|
+
get(): boolean;
|
|
57
|
+
set(setter: boolean | ((prevState: boolean) => boolean)): void;
|
|
58
|
+
}>>;
|
|
59
|
+
private readonly _internals;
|
|
60
|
+
private readonly _refs;
|
|
61
|
+
focus(options?: FocusOptions): void;
|
|
62
|
+
templateHtml(): Node;
|
|
63
|
+
templateCss(): string;
|
|
64
|
+
onConnect(): void;
|
|
65
|
+
private actOnForm;
|
|
66
|
+
private renderIcon;
|
|
67
|
+
private renderSize;
|
|
68
|
+
private hasSlottedContent;
|
|
69
|
+
private renderLabel;
|
|
70
|
+
}
|