@kubex/zinc 1.0.113 ā 1.0.115
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/.github/workflows/eleventy_build.yml +5 -5
- package/.github/workflows/js_build_and_deploy.yaml +1 -1
- package/dist/custom-elements.json +2422 -190
- package/dist/vscode.html-custom-data.json +86 -5
- package/dist/web-types.json +251 -9
- package/dist/zn.d.ts +518 -340
- package/dist/zn.min.css +1 -1
- package/dist/zn.min.js +960 -882
- package/docs/eleventy.config.cjs +4 -2
- package/docs/pages/components/header.md +13 -0
- package/docs/pages/components/inline-edit.md +20 -0
- package/docs/pages/components/item.md +12 -1
- package/docs/pages/components/page.md +149 -0
- package/docs/pages/components/progress-bar.md +16 -0
- package/docs/pages/components/select.md +25 -0
- package/docs/pages/components/split-pane.md +6 -7
- package/docs/pages/components/tabs.md +59 -9
- package/package.json +8 -5
- package/scripts/build.js +40 -19
- package/scss/_global-spacing.scss +12 -1
- package/scss/_root.scss +34 -2
- package/scss/mixins/_spacing-mixins.scss +1 -1
- package/scss/shared/layout.scss +15 -2
- package/scss/themes/_light.scss +1 -1
- package/src/components/absolute-container/absolute-container.component.ts +9 -25
- package/src/components/animated-button/animated-button.test.ts +8 -8
- package/src/components/button/button.component.ts +3 -1
- package/src/components/button/button.scss +5 -0
- package/src/components/button-menu/button-menu.component.ts +36 -21
- package/src/components/button-menu/button-menu.test.ts +55 -1
- package/src/components/chart/chart.component.ts +7 -7
- package/src/components/collapsible/collapsible.component.ts +7 -14
- package/src/components/cols/cols.scss +1 -1
- package/src/components/content-block/content-block.component.ts +11 -33
- package/src/components/data-select/data-select.component.ts +7 -11
- package/src/components/data-select/data-select.scss +1 -0
- package/src/components/data-table/data-table.component.ts +10 -14
- package/src/components/dialog/dialog.scss +4 -0
- package/src/components/editor/modules/toolbar/toolbar.component.ts +5 -9
- package/src/components/expanding-action/expanding-action.component.ts +37 -43
- package/src/components/form-group/form-group.component.ts +32 -27
- package/src/components/form-group/form-group.scss +1 -0
- package/src/components/header/header.component.ts +6 -5
- package/src/components/header/header.scss +28 -26
- package/src/components/inline-edit/inline-edit.component.ts +13 -1
- package/src/components/inline-edit/inline-edit.test.ts +50 -0
- package/src/components/input/input.test.ts +77 -0
- package/src/components/input-group/input-group.test.ts +2 -10
- package/src/components/item/item.component.ts +12 -6
- package/src/components/item/item.scss +1 -1
- package/src/components/item/item.test.ts +8 -0
- package/src/components/navbar/navbar.component.ts +222 -48
- package/src/components/navbar/navbar.scss +134 -21
- package/src/components/navbar/navbar.test.ts +114 -9
- package/src/components/option/option.scss +5 -7
- package/src/components/option/option.test.ts +30 -0
- package/src/components/page/index.ts +13 -0
- package/src/components/page/page.component.ts +406 -0
- package/src/components/page/page.scss +325 -0
- package/src/components/page/page.test.ts +397 -0
- package/src/components/page-nav/page-nav.scss +7 -5
- package/src/components/pane/pane.component.ts +2 -2
- package/src/components/pane/pane.scss +0 -1
- package/src/components/pane/pane.test.ts +31 -0
- package/src/components/panel/panel.scss +5 -16
- package/src/components/progress-bar/progress-bar.component.ts +5 -2
- package/src/components/progress-bar/progress-bar.scss +17 -1
- package/src/components/progress-bar/progress-bar.test.ts +12 -0
- package/src/components/scroll-container/scroll-container.component.ts +22 -21
- package/src/components/select/select.component.ts +243 -39
- package/src/components/select/select.scss +36 -5
- package/src/components/select/select.test.ts +533 -0
- package/src/components/settings-container/settings-container.component.ts +15 -19
- package/src/components/settings-container/settings-container.scss +8 -8
- package/src/components/sidebar/sidebar.component.ts +11 -11
- package/src/components/simple-chart/simple-chart.component.ts +6 -7
- package/src/components/sp/sp.scss +46 -15
- package/src/components/sp/sp.test.ts +15 -0
- package/src/components/split-pane/split-pane.component.ts +153 -26
- package/src/components/split-pane/split-pane.scss +89 -13
- package/src/components/split-pane/split-pane.test.ts +187 -0
- package/src/components/style/style.component.ts +8 -0
- package/src/components/tab/index.ts +13 -0
- package/src/components/tab/tab.component.ts +25 -0
- package/src/components/tab/tab.scss +7 -0
- package/src/components/table/table.component.ts +7 -2
- package/src/components/table/table.scss +1 -0
- package/src/components/tabs/tabs.component.ts +75 -70
- package/src/components/tabs/tabs.scss +1 -1
- package/src/components/textarea/textarea.component.ts +5 -8
- package/src/components/tile/tile.scss +2 -2
- package/src/components/translation-group/translation-group.component.ts +15 -14
- package/src/components/translations/translations.component.ts +18 -17
- package/src/components/translations/translations.scss +1 -0
- package/src/components/translations/translations.test.ts +3 -2
- package/src/internal/form.ts +234 -0
- package/src/internal/theme.ts +26 -46
- package/src/internal/zinc-element.ts +12 -7
- package/src/utilities/form.ts +1 -0
- package/src/wc.scss +1 -1
- package/src/zinc.ts +3 -0
package/docs/eleventy.config.cjs
CHANGED
|
@@ -93,12 +93,14 @@ module.exports = function (eleventyConfig)
|
|
|
93
93
|
//
|
|
94
94
|
eleventyConfig.addFilter('markdown', content =>
|
|
95
95
|
{
|
|
96
|
-
|
|
96
|
+
// CEM members (events, slots, CSS props/parts, animations) may have no description, in which case
|
|
97
|
+
// `content` is undefined. markdown-it calls .replace on its input and would throw, so coerce to ''.
|
|
98
|
+
return typeof content === 'string' ? zincFlavoredMarkdown.render(content) : '';
|
|
97
99
|
});
|
|
98
100
|
|
|
99
101
|
eleventyConfig.addFilter('markdownInline', content =>
|
|
100
102
|
{
|
|
101
|
-
return zincFlavoredMarkdown.renderInline(content);
|
|
103
|
+
return typeof content === 'string' ? zincFlavoredMarkdown.renderInline(content) : '';
|
|
102
104
|
});
|
|
103
105
|
|
|
104
106
|
// Trims whitespace and pipes from the start and end of a string. Useful for CEM types, which can be pipe-delimited.
|
|
@@ -20,8 +20,21 @@ layout: component
|
|
|
20
20
|
</div>
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
+
The breadcrumb slot renders inline with the page title ā each slotted link is followed by a `>` separator and the `caption` becomes the final, unlinked item in the trail. Set `hide-breadcrumb` to suppress the trail and show only the title.
|
|
24
|
+
|
|
23
25
|
## Examples
|
|
24
26
|
|
|
27
|
+
### Hide breadcrumb
|
|
28
|
+
|
|
29
|
+
```html:preview
|
|
30
|
+
<div style="background-color: #f5f5f5; padding: 20px;">
|
|
31
|
+
<zn-header caption="John Jones" hide-breadcrumb>
|
|
32
|
+
<a href="#" slot="breadcrumb">Dashboard</a>
|
|
33
|
+
<a href="#" slot="breadcrumb">Another</a>
|
|
34
|
+
</zn-header>
|
|
35
|
+
</div>
|
|
36
|
+
```
|
|
37
|
+
|
|
25
38
|
### Simple Header
|
|
26
39
|
|
|
27
40
|
```html:preview
|
|
@@ -151,6 +151,26 @@ Add the `search` attribute to enable filtering on select inputs. Users can type
|
|
|
151
151
|
</div>
|
|
152
152
|
```
|
|
153
153
|
|
|
154
|
+
### Free Text Select
|
|
155
|
+
|
|
156
|
+
Add the `free-text` attribute to let users enter values that aren't in the options list (see [`zn-select`](/components/select#free-text-entry)). `free-text` implies a select input, so you don't need `input-type="select"`. Combine it with `multiple` for a tag-style editor.
|
|
157
|
+
|
|
158
|
+
```html:preview
|
|
159
|
+
<div class="form-spacing">
|
|
160
|
+
<zn-inline-edit name="status" value="active" free-text>
|
|
161
|
+
<zn-option value="active">Active</zn-option>
|
|
162
|
+
<zn-option value="inactive">Inactive</zn-option>
|
|
163
|
+
<zn-option value="pending">Pending</zn-option>
|
|
164
|
+
</zn-inline-edit>
|
|
165
|
+
|
|
166
|
+
<zn-inline-edit name="tags" free-text multiple value="urgent backend">
|
|
167
|
+
<zn-option value="urgent">Urgent</zn-option>
|
|
168
|
+
<zn-option value="backend">Backend</zn-option>
|
|
169
|
+
<zn-option value="frontend">Frontend</zn-option>
|
|
170
|
+
</zn-inline-edit>
|
|
171
|
+
</div>
|
|
172
|
+
```
|
|
173
|
+
|
|
154
174
|
### Data Select with Provider
|
|
155
175
|
|
|
156
176
|
Use the `provider` attribute to integrate with data select providers like countries, currencies, or colors.
|
|
@@ -37,6 +37,18 @@ layout: component
|
|
|
37
37
|
</zn-item>
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
+
### Right Aligned Content
|
|
41
|
+
|
|
42
|
+
Use `align-end` to right align the content value.
|
|
43
|
+
|
|
44
|
+
```html:preview
|
|
45
|
+
<zn-sp divide no-gap>
|
|
46
|
+
<zn-item caption="Subtotal" align-end>$120.00</zn-item>
|
|
47
|
+
<zn-item caption="Tax" align-end>$24.00</zn-item>
|
|
48
|
+
<zn-item caption="Total" align-end>$144.00</zn-item>
|
|
49
|
+
</zn-sp>
|
|
50
|
+
```
|
|
51
|
+
|
|
40
52
|
### Icons
|
|
41
53
|
|
|
42
54
|
```html:preview
|
|
@@ -93,4 +105,3 @@ Example of multiple actions in a description item.
|
|
|
93
105
|
|
|
94
106
|
</zn-item>
|
|
95
107
|
```
|
|
96
|
-
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
---
|
|
2
|
+
meta:
|
|
3
|
+
title: Page
|
|
4
|
+
description: Pages combine a header with tabbed content.
|
|
5
|
+
layout: component
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
```html:preview
|
|
9
|
+
<zn-page caption="Page Title" summary="Page Summary">
|
|
10
|
+
<zn-button slot="actions" type="primary" size="small" href="/ui">UI Examples</zn-button>
|
|
11
|
+
|
|
12
|
+
<zn-tab caption="Overview">
|
|
13
|
+
Overview Content
|
|
14
|
+
</zn-tab>
|
|
15
|
+
|
|
16
|
+
<zn-tab caption="Tab One">
|
|
17
|
+
Tab One Content
|
|
18
|
+
</zn-tab>
|
|
19
|
+
|
|
20
|
+
<zn-tab caption="Tab Two" id="tab-2">
|
|
21
|
+
Tab Two Content
|
|
22
|
+
</zn-tab>
|
|
23
|
+
|
|
24
|
+
<zn-tab caption="Dynamic Tab" uri="/tab-three"></zn-tab>
|
|
25
|
+
</zn-page>
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Examples
|
|
29
|
+
|
|
30
|
+
### Header Actions
|
|
31
|
+
|
|
32
|
+
Use `slot="actions"` to place controls in the page header action area.
|
|
33
|
+
|
|
34
|
+
```html:preview
|
|
35
|
+
<zn-page caption="Customers" summary="Manage active customers">
|
|
36
|
+
<zn-button slot="actions" color="secondary" size="small">Export</zn-button>
|
|
37
|
+
<zn-button slot="actions" color="primary" size="small">New Customer</zn-button>
|
|
38
|
+
|
|
39
|
+
<zn-tab caption="Overview">
|
|
40
|
+
Customer overview content
|
|
41
|
+
</zn-tab>
|
|
42
|
+
|
|
43
|
+
<zn-tab caption="Active">
|
|
44
|
+
Active customer content
|
|
45
|
+
</zn-tab>
|
|
46
|
+
|
|
47
|
+
<zn-tab caption="Archived">
|
|
48
|
+
Archived customer content
|
|
49
|
+
</zn-tab>
|
|
50
|
+
</zn-page>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Header Metadata
|
|
54
|
+
|
|
55
|
+
`zn-page` supports the same header metadata attributes as `zn-header`: `full-location`, `entity-id`, `entity-id-show`, `previous-path`, and `previous-target`.
|
|
56
|
+
|
|
57
|
+
```html:preview
|
|
58
|
+
<zn-page
|
|
59
|
+
caption="Customer Comms"
|
|
60
|
+
summary="This is a description about the purpose of this page."
|
|
61
|
+
full-location="/customers/comms"
|
|
62
|
+
entity-id="customer-comms"
|
|
63
|
+
previous-path="/customers">
|
|
64
|
+
<zn-tab caption="Overview">
|
|
65
|
+
Overview content
|
|
66
|
+
</zn-tab>
|
|
67
|
+
</zn-page>
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Breadcrumbs
|
|
71
|
+
|
|
72
|
+
Breadcrumb links can be passed with `slot="breadcrumb"` and will be forwarded to the underlying header.
|
|
73
|
+
|
|
74
|
+
```html:preview
|
|
75
|
+
<zn-page caption="Account Settings" summary="Configure account preferences">
|
|
76
|
+
<a href="#" slot="breadcrumb">Accounts</a>
|
|
77
|
+
<a href="#" slot="breadcrumb">Acme Inc</a>
|
|
78
|
+
|
|
79
|
+
<zn-tab caption="Profile">
|
|
80
|
+
Profile content
|
|
81
|
+
</zn-tab>
|
|
82
|
+
|
|
83
|
+
<zn-tab caption="Security">
|
|
84
|
+
Security content
|
|
85
|
+
</zn-tab>
|
|
86
|
+
</zn-page>
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Overview Content
|
|
90
|
+
|
|
91
|
+
Use a normal `zn-tab` for overview content. An Overview tab without an explicit `id` uses the default empty tab id. `zn-page` leaves tab elements in the page light DOM and projects them into internal tab panels, so scoped styles from the original DOM context continue to apply.
|
|
92
|
+
Tabs render in the order they appear in the page by default. Tabs with an empty id are shown first. Set `priority` on `zn-tab` to order the remaining tabs without changing their DOM position.
|
|
93
|
+
|
|
94
|
+
```html:preview
|
|
95
|
+
<zn-page caption="Project" summary="Current project status">
|
|
96
|
+
<zn-tab caption="Overview">
|
|
97
|
+
<zn-note open>
|
|
98
|
+
This summary appears in the Overview tab.
|
|
99
|
+
</zn-note>
|
|
100
|
+
</zn-tab>
|
|
101
|
+
|
|
102
|
+
<zn-tab caption="Activity">
|
|
103
|
+
Activity content
|
|
104
|
+
</zn-tab>
|
|
105
|
+
|
|
106
|
+
<zn-tab caption="Files">
|
|
107
|
+
Files content
|
|
108
|
+
</zn-tab>
|
|
109
|
+
</zn-page>
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Tab Priority
|
|
113
|
+
|
|
114
|
+
Use `priority` to control tab order. Lower numbers appear first after the empty-id overview tab.
|
|
115
|
+
|
|
116
|
+
```html:preview
|
|
117
|
+
<zn-page caption="Ordered Page" summary="Priority controls the navigation order">
|
|
118
|
+
<zn-tab caption="Later">
|
|
119
|
+
Later content
|
|
120
|
+
</zn-tab>
|
|
121
|
+
|
|
122
|
+
<zn-tab caption="Second" priority="20">
|
|
123
|
+
Second content
|
|
124
|
+
</zn-tab>
|
|
125
|
+
|
|
126
|
+
<zn-tab caption="Overview">
|
|
127
|
+
Overview content
|
|
128
|
+
</zn-tab>
|
|
129
|
+
|
|
130
|
+
<zn-tab caption="First" priority="10">
|
|
131
|
+
First content
|
|
132
|
+
</zn-tab>
|
|
133
|
+
</zn-page>
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Dynamic Tabs
|
|
137
|
+
|
|
138
|
+
Set `uri` on `zn-tab` to create a dynamic tab. The generated navigation item receives `tab-uri`.
|
|
139
|
+
|
|
140
|
+
```html:preview
|
|
141
|
+
<zn-page caption="Reports" summary="Load reports on demand">
|
|
142
|
+
<zn-tab caption="Overview">
|
|
143
|
+
Report overview content
|
|
144
|
+
</zn-tab>
|
|
145
|
+
|
|
146
|
+
<zn-tab caption="Revenue" uri="/reports/revenue"></zn-tab>
|
|
147
|
+
<zn-tab caption="Usage" uri="/reports/usage"></zn-tab>
|
|
148
|
+
</zn-page>
|
|
149
|
+
```
|
|
@@ -25,6 +25,22 @@ A basic progress bar displays the completion percentage using the `value` attrib
|
|
|
25
25
|
<zn-progress-bar value="100"></zn-progress-bar>
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
+
### Color Options
|
|
29
|
+
|
|
30
|
+
Use the `color` attribute to set the progress fill color. Supported options are `current`, `info`, `danger`, `success`, and `warning`.
|
|
31
|
+
|
|
32
|
+
```html:preview
|
|
33
|
+
<zn-progress-bar color="current" value="40"></zn-progress-bar>
|
|
34
|
+
<br />
|
|
35
|
+
<zn-progress-bar color="info" value="50"></zn-progress-bar>
|
|
36
|
+
<br />
|
|
37
|
+
<zn-progress-bar color="danger" value="60"></zn-progress-bar>
|
|
38
|
+
<br />
|
|
39
|
+
<zn-progress-bar color="success" value="70"></zn-progress-bar>
|
|
40
|
+
<br />
|
|
41
|
+
<zn-progress-bar color="warning" value="80"></zn-progress-bar>
|
|
42
|
+
```
|
|
43
|
+
|
|
28
44
|
### With Caption
|
|
29
45
|
|
|
30
46
|
Use the `caption` attribute to add a label above the progress bar. This helps identify what the progress bar represents.
|
|
@@ -185,6 +185,31 @@ Combine `search` with `multiple` to allow users to search and select multiple op
|
|
|
185
185
|
</zn-select>
|
|
186
186
|
```
|
|
187
187
|
|
|
188
|
+
### Free Text Entry
|
|
189
|
+
|
|
190
|
+
Use the `free-text` attribute to let users enter values that aren't in the options list. `free-text` implies the editable, filtering input behavior of `search`, so users can both filter existing options and add their own. When the typed text doesn't match an existing option, an **Add "ā¦"** row appears at the top of the listbox; committing it (by pressing <kbd>Enter</kbd>, clicking the Add row, or blurring the field) adds the value as a selection. A committed value becomes both the option's value and its label.
|
|
191
|
+
|
|
192
|
+
If the typed text exactly matches an existing option (by label or value, case-insensitive), the Add row is suppressed and the existing option is selected instead ā so no duplicates are created.
|
|
193
|
+
|
|
194
|
+
```html:preview
|
|
195
|
+
<zn-select label="Add tags" free-text placeholder="Type a tag and press Enter">
|
|
196
|
+
<zn-option value="bug">Bug</zn-option>
|
|
197
|
+
<zn-option value="feature">Feature</zn-option>
|
|
198
|
+
<zn-option value="chore">Chore</zn-option>
|
|
199
|
+
</zn-select>
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Free Text with Multiple Selection
|
|
203
|
+
|
|
204
|
+
Combine `free-text` with `multiple` to build a tag-style input. Each committed value is added as a tag and the input stays open so users can keep entering values. Removing a tag whose value was entered as free text deletes it entirely.
|
|
205
|
+
|
|
206
|
+
```html:preview
|
|
207
|
+
<zn-select label="Recipients" free-text multiple clearable placeholder="Add email addresses...">
|
|
208
|
+
<zn-option value="support@example.com">support@example.com</zn-option>
|
|
209
|
+
<zn-option value="sales@example.com">sales@example.com</zn-option>
|
|
210
|
+
</zn-select>
|
|
211
|
+
```
|
|
212
|
+
|
|
188
213
|
### Remote Search
|
|
189
214
|
|
|
190
215
|
When `search` and `data-uri` are used together, typing in the select sends debounced requests to the server instead of filtering locally. The search term is appended as a query parameter (default `q`). Use `search-param` to customise the parameter name, `search-debounce` to control the delay, and `max-results` to cap displayed results.
|
|
@@ -67,15 +67,15 @@ Use the `pixels` attribute to switch from percentage-based sizing to pixel-based
|
|
|
67
67
|
|
|
68
68
|
### Min and Max Size
|
|
69
69
|
|
|
70
|
-
Use `min-size` and `max-size` to constrain how much users can resize the primary pane. These values match the unit type (percentage or pixels).
|
|
70
|
+
Use `min-size` and `max-size` to constrain how much users can resize the primary pane. Use `min-secondary-size` to keep the secondary pane above a minimum size. These values match the unit type (percentage or pixels).
|
|
71
71
|
|
|
72
72
|
```html:preview
|
|
73
|
-
<zn-split-pane min-size="20" max-size="80" style="height: 300px;">
|
|
73
|
+
<zn-split-pane min-size="20" max-size="80" min-secondary-size="30" style="height: 300px;">
|
|
74
74
|
<div slot="primary" style="padding: 20px; background: #f5f5f5;">
|
|
75
|
-
<p>Primary pane can be resized between 20% and
|
|
75
|
+
<p>Primary pane can be resized between 20% and 70%</p>
|
|
76
76
|
</div>
|
|
77
77
|
<div slot="secondary" style="padding: 20px;">
|
|
78
|
-
<p>Secondary pane
|
|
78
|
+
<p>Secondary pane stays at least 30%</p>
|
|
79
79
|
</div>
|
|
80
80
|
</zn-split-pane>
|
|
81
81
|
```
|
|
@@ -83,12 +83,12 @@ Use `min-size` and `max-size` to constrain how much users can resize the primary
|
|
|
83
83
|
With pixel sizing:
|
|
84
84
|
|
|
85
85
|
```html:preview
|
|
86
|
-
<zn-split-pane pixels min-size="150" max-size="400" initial-size="250" style="height: 300px;">
|
|
86
|
+
<zn-split-pane pixels min-size="150" max-size="400" min-secondary-size="200" initial-size="250" style="height: 300px;">
|
|
87
87
|
<div slot="primary" style="padding: 20px; background: #f5f5f5;">
|
|
88
88
|
<p>Primary pane can be resized between 150px and 400px</p>
|
|
89
89
|
</div>
|
|
90
90
|
<div slot="secondary" style="padding: 20px;">
|
|
91
|
-
<p>Secondary pane
|
|
91
|
+
<p>Secondary pane stays at least 200px wide</p>
|
|
92
92
|
</div>
|
|
93
93
|
</zn-split-pane>
|
|
94
94
|
```
|
|
@@ -458,4 +458,3 @@ The split pane exposes CSS variables for advanced customization.
|
|
|
458
458
|
</div>
|
|
459
459
|
</zn-split-pane>
|
|
460
460
|
```
|
|
461
|
-
|
|
@@ -28,7 +28,9 @@ layout: component
|
|
|
28
28
|
|
|
29
29
|
### Basic Tabs
|
|
30
30
|
|
|
31
|
-
The tabs component works by connecting tab navigation elements (typically in a `zn-navbar` in the `top` slot) with
|
|
31
|
+
The tabs component works by connecting tab navigation elements (typically in a `zn-navbar` in the `top` slot) with
|
|
32
|
+
content panels. Each panel is identified by an `id` attribute, and navigation items use a `tab` attribute to reference
|
|
33
|
+
those IDs.
|
|
32
34
|
|
|
33
35
|
```html:preview
|
|
34
36
|
<zn-tabs flush>
|
|
@@ -52,6 +54,46 @@ The tabs component works by connecting tab navigation elements (typically in a `
|
|
|
52
54
|
</zn-tabs>
|
|
53
55
|
```
|
|
54
56
|
|
|
57
|
+
### Overflow
|
|
58
|
+
|
|
59
|
+
When there are more tabs than can fit in the available space, the component will automatically show an overflow menu.
|
|
60
|
+
This allows users to access all tabs even on smaller screens.
|
|
61
|
+
|
|
62
|
+
```html:preview
|
|
63
|
+
<zn-tabs flush>
|
|
64
|
+
<zn-navbar slot="top">
|
|
65
|
+
<li tab="">Tab 1</li>
|
|
66
|
+
<li tab="tab2">Lorem IPsum dolor sit amet. Lorem Ipsum Dolor sit Amet</li>
|
|
67
|
+
<li tab="tab3">Tab 3</li>
|
|
68
|
+
<li tab="tab4">Tab 4</li>
|
|
69
|
+
<li tab="tab5">This is Tab 5</li>
|
|
70
|
+
<li tab="tab6">This is Tab 6</li>
|
|
71
|
+
<li tab="tab7">This is Tab 7</li>
|
|
72
|
+
</zn-navbar>
|
|
73
|
+
<zn-sp id="">
|
|
74
|
+
<p>Content for Tab 1.</p>
|
|
75
|
+
</zn-sp>
|
|
76
|
+
<zn-sp id="tab2">
|
|
77
|
+
<p>Content for Tab 2.</p>
|
|
78
|
+
</zn-sp>
|
|
79
|
+
<zn-sp id="tab3">
|
|
80
|
+
<p>Content for Tab 3.</p>
|
|
81
|
+
</zn-sp>
|
|
82
|
+
<zn-sp id="tab4">
|
|
83
|
+
<p>Content for Tab 4.</p>
|
|
84
|
+
</zn-sp>
|
|
85
|
+
<zn-sp id="tab5">
|
|
86
|
+
<p>Content for Tab 5.</p>
|
|
87
|
+
</zn-sp>
|
|
88
|
+
<zn-sp id="tab6">
|
|
89
|
+
<p>Content for Tab 6.</p>
|
|
90
|
+
</zn-sp>
|
|
91
|
+
<zn-sp id="tab7">
|
|
92
|
+
<p>Content for Tab 7.</p>
|
|
93
|
+
</zn-sp>
|
|
94
|
+
</zn-tabs>
|
|
95
|
+
```
|
|
96
|
+
|
|
55
97
|
### With Caption and Description
|
|
56
98
|
|
|
57
99
|
Use the `caption` and `description` attributes to add a header to your tabs component.
|
|
@@ -103,7 +145,8 @@ Remove the `caption` attribute for a cleaner layout when a header is not needed.
|
|
|
103
145
|
|
|
104
146
|
### Dynamic Tabs with URI Loading
|
|
105
147
|
|
|
106
|
-
Use the `tab-uri` attribute to load content dynamically from a URL when a tab is clicked. The component will
|
|
148
|
+
Use the `tab-uri` attribute to load content dynamically from a URL when a tab is clicked. The component will
|
|
149
|
+
automatically fetch and display the content.
|
|
107
150
|
|
|
108
151
|
```html:preview
|
|
109
152
|
<zn-tabs flush no-prefetch>
|
|
@@ -117,7 +160,8 @@ Use the `tab-uri` attribute to load content dynamically from a URL when a tab is
|
|
|
117
160
|
|
|
118
161
|
### Prefetching
|
|
119
162
|
|
|
120
|
-
By default, tabs with `tab-uri` will prefetch content on hover. Use the `no-prefetch` attribute to disable this behavior
|
|
163
|
+
By default, tabs with `tab-uri` will prefetch content on hover. Use the `no-prefetch` attribute to disable this behavior
|
|
164
|
+
and only load content when clicked.
|
|
121
165
|
|
|
122
166
|
```html:preview
|
|
123
167
|
<zn-tabs flush no-prefetch>
|
|
@@ -156,7 +200,8 @@ Use the `active` attribute to specify which tab should be active by default.
|
|
|
156
200
|
|
|
157
201
|
### Storage Persistence
|
|
158
202
|
|
|
159
|
-
Use `store-key` to persist the active tab selection across page reloads. By default, uses session storage with a
|
|
203
|
+
Use `store-key` to persist the active tab selection across page reloads. By default, uses session storage with a
|
|
204
|
+
5-minute TTL. Use `local-storage` for persistent storage beyond the session.
|
|
160
205
|
|
|
161
206
|
```html:preview
|
|
162
207
|
<zn-tabs flush store-key="my-tabs">
|
|
@@ -182,7 +227,8 @@ Use `store-key` to persist the active tab selection across page reloads. By defa
|
|
|
182
227
|
|
|
183
228
|
### Local Storage
|
|
184
229
|
|
|
185
|
-
Use `local-storage` with `store-key` to persist tabs across browser sessions. Control expiration with `store-ttl` (in
|
|
230
|
+
Use `local-storage` with `store-key` to persist tabs across browser sessions. Control expiration with `store-ttl` (in
|
|
231
|
+
seconds).
|
|
186
232
|
|
|
187
233
|
```html:preview
|
|
188
234
|
<zn-tabs flush store-key="persistent-tabs" local-storage store-ttl="86400">
|
|
@@ -268,10 +314,12 @@ Use the `full-width` attribute to make tab content expand to fill the available
|
|
|
268
314
|
|
|
269
315
|
### Split Pane Layout
|
|
270
316
|
|
|
271
|
-
Use the `split` attribute with a pixel value to create a split pane layout with resizable sections. Control minimum and
|
|
317
|
+
Use the `split` attribute with a pixel value to create a split pane layout with resizable sections. Control minimum and
|
|
318
|
+
maximum primary sizes with `split-min` and `split-max`, and keep the secondary pane above a minimum width with
|
|
319
|
+
`split-min-secondary`.
|
|
272
320
|
|
|
273
321
|
```html:preview
|
|
274
|
-
<zn-tabs split="300" split-min="200" split-max="600">
|
|
322
|
+
<zn-tabs split="300" split-min="200" split-max="600" split-min-secondary="320">
|
|
275
323
|
<zn-navbar slot="left">
|
|
276
324
|
<li tab="">Navigation</li>
|
|
277
325
|
<li tab="menu2">Menu 2</li>
|
|
@@ -344,7 +392,8 @@ The tabs component provides multiple slots for flexible layouts.
|
|
|
344
392
|
|
|
345
393
|
### Actions Slot
|
|
346
394
|
|
|
347
|
-
Use the `actions` slot to add action buttons that appear in the header. Elements can be conditionally shown based on the
|
|
395
|
+
Use the `actions` slot to add action buttons that appear in the header. Elements can be conditionally shown based on the
|
|
396
|
+
active tab using `ref-tab`.
|
|
348
397
|
|
|
349
398
|
```html:preview
|
|
350
399
|
<zn-tabs caption="Document Editor">
|
|
@@ -418,7 +467,8 @@ Access tab methods programmatically to switch tabs, navigate, or refresh content
|
|
|
418
467
|
|
|
419
468
|
### Tab Refresh
|
|
420
469
|
|
|
421
|
-
Triple-clicking an active tab or using the refresh parameter will reload dynamic content. Hold Alt while clicking to
|
|
470
|
+
Triple-clicking an active tab or using the refresh parameter will reload dynamic content. Hold Alt while clicking to
|
|
471
|
+
force a refresh.
|
|
422
472
|
|
|
423
473
|
```html:preview
|
|
424
474
|
<zn-tabs flush>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kubex/zinc",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.115",
|
|
4
4
|
"description": "A collection of web components for building web applications based off of @shoelace-style/Shoelace",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"web components",
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
"unpkg": "dist/zinc.min.js",
|
|
29
29
|
"scripts": {
|
|
30
30
|
"build": "node scripts/build.js",
|
|
31
|
+
"build:docs": "node scripts/build.js --with-docs",
|
|
31
32
|
"build:vite": "vite build",
|
|
32
33
|
"check-updates": "npx npm-check-updates --interactive --format group",
|
|
33
34
|
"create": "plop --plopfile scripts/plop/plopfile.js",
|
|
@@ -37,19 +38,21 @@
|
|
|
37
38
|
"test": "npx playwright install --with-deps && web-test-runner --group default",
|
|
38
39
|
"test:component": "npx playwright install --with-deps && web-test-runner -- --watch --group",
|
|
39
40
|
"test:watch": "npx playwright install --with-deps && web-test-runner --watch --group default",
|
|
40
|
-
"watch": "node scripts/build.js --serve"
|
|
41
|
+
"watch": "node scripts/build.js --serve",
|
|
42
|
+
"watch:docs": "node scripts/build.js --serve --with-docs"
|
|
41
43
|
},
|
|
42
44
|
"dependencies": {
|
|
43
45
|
"@emoji-mart/data": "^1.2.1",
|
|
44
46
|
"@floating-ui/dom": "^1.6.13",
|
|
45
47
|
"@lit-labs/observers": "^2.0.4",
|
|
48
|
+
"@lit-labs/signals": "^0.3.0",
|
|
46
49
|
"@lit/task": "^1.0.1",
|
|
47
50
|
"@shoelace-style/localize": "^3.2.1",
|
|
48
51
|
"air-datepicker": "^3.5.3",
|
|
49
52
|
"composed-offset-position": "^0.0.6",
|
|
50
53
|
"echarts": "^6.0.0",
|
|
51
54
|
"emoji-mart": "^5.6.0",
|
|
52
|
-
"lit": "^
|
|
55
|
+
"lit": "^3.3.3",
|
|
53
56
|
"marked": "^18.0.2",
|
|
54
57
|
"quill": "^2.0.3"
|
|
55
58
|
},
|
|
@@ -115,9 +118,9 @@
|
|
|
115
118
|
"strip-css-comments": "^5.0.0",
|
|
116
119
|
"tailwindcss": "^3.4.17",
|
|
117
120
|
"tslib": "^2.8.1",
|
|
118
|
-
"typescript": "
|
|
121
|
+
"typescript": "5.8.3",
|
|
119
122
|
"user-agent-data-types": "^0.4.2"
|
|
120
123
|
},
|
|
121
|
-
"customElements": "
|
|
124
|
+
"customElements": "dist/custom-elements.json",
|
|
122
125
|
"web-types": "./dist/web-types.json"
|
|
123
126
|
}
|
package/scripts/build.js
CHANGED
|
@@ -21,7 +21,10 @@ const postCss = postCSS([
|
|
|
21
21
|
minify()
|
|
22
22
|
]);
|
|
23
23
|
|
|
24
|
-
const {serve} = commandLineArgs([
|
|
24
|
+
const {serve, 'with-docs': withDocs} = commandLineArgs([
|
|
25
|
+
{name: 'serve', type: Boolean},
|
|
26
|
+
{name: 'with-docs', type: Boolean}
|
|
27
|
+
]);
|
|
25
28
|
const outDir = 'dist';
|
|
26
29
|
const siteDir = '_site';
|
|
27
30
|
const spinner = ora({hideCursor: false}).start();
|
|
@@ -256,13 +259,16 @@ if(serve)
|
|
|
256
259
|
{
|
|
257
260
|
let result;
|
|
258
261
|
|
|
259
|
-
|
|
260
|
-
// eleventy.after, so it appears after the docs are fully published. This is kinda hacky, but here we are.
|
|
261
|
-
// Kick off the Eleventy dev server with --watch and --incremental
|
|
262
|
-
await nextTask('Building the docs', async () =>
|
|
262
|
+
if(withDocs)
|
|
263
263
|
{
|
|
264
|
-
|
|
265
|
-
|
|
264
|
+
// Spin up Eleventy and Wait for the search index to appear before proceeding. The search index is generated during
|
|
265
|
+
// eleventy.after, so it appears after the docs are fully published. This is kinda hacky, but here we are.
|
|
266
|
+
// Kick off the Eleventy dev server with --watch and --incremental
|
|
267
|
+
await nextTask('Building the docs', async () =>
|
|
268
|
+
{
|
|
269
|
+
result = await buildTheDocs(true);
|
|
270
|
+
});
|
|
271
|
+
}
|
|
266
272
|
|
|
267
273
|
const bs = browserSync.create();
|
|
268
274
|
const port = await getPort({port: portNumbers(4000, 4999)});
|
|
@@ -275,31 +281,43 @@ if(serve)
|
|
|
275
281
|
notify: false,
|
|
276
282
|
single: false,
|
|
277
283
|
ghostMode: false,
|
|
278
|
-
|
|
284
|
+
open: withDocs,
|
|
285
|
+
ui: withDocs ? undefined : false,
|
|
286
|
+
server: withDocs ? {
|
|
279
287
|
baseDir: siteDir,
|
|
280
288
|
routes: {
|
|
281
289
|
'/dist': outDir
|
|
282
290
|
}
|
|
283
|
-
}
|
|
291
|
+
} : false
|
|
284
292
|
};
|
|
285
293
|
|
|
286
294
|
// Launch BrowserSync
|
|
287
295
|
bs.init(bsConfig, () =>
|
|
288
296
|
{
|
|
289
|
-
|
|
290
|
-
|
|
297
|
+
if(withDocs)
|
|
298
|
+
{
|
|
299
|
+
const url = `http://localhost:${port}`;
|
|
300
|
+
console.log(chalk.cyan(`\nš Server running at ${url}`));
|
|
301
|
+
}
|
|
302
|
+
else
|
|
303
|
+
{
|
|
304
|
+
console.log(chalk.cyan('\nš Watching source files (run with --with-docs for the docs server)'));
|
|
305
|
+
}
|
|
291
306
|
|
|
292
307
|
// log deferred output
|
|
293
|
-
if(result.output.length > 0)
|
|
308
|
+
if(result && result.output.length > 0)
|
|
294
309
|
{
|
|
295
310
|
console.log('\n' + result.output.join('\n'));
|
|
296
311
|
}
|
|
297
312
|
|
|
298
313
|
// Log output that comes later on
|
|
299
|
-
result
|
|
314
|
+
if(result)
|
|
300
315
|
{
|
|
301
|
-
|
|
302
|
-
|
|
316
|
+
result.child.stdout.on('data', data =>
|
|
317
|
+
{
|
|
318
|
+
console.log(data.toString());
|
|
319
|
+
});
|
|
320
|
+
}
|
|
303
321
|
});
|
|
304
322
|
|
|
305
323
|
// Rebuild and reload then source files change
|
|
@@ -351,15 +369,18 @@ if(serve)
|
|
|
351
369
|
});
|
|
352
370
|
|
|
353
371
|
// Reload without rebuilding when docs change
|
|
354
|
-
|
|
372
|
+
if(withDocs)
|
|
355
373
|
{
|
|
356
|
-
bs.
|
|
357
|
-
|
|
374
|
+
bs.watch([`${siteDir}/**/*.*`]).on('change', () =>
|
|
375
|
+
{
|
|
376
|
+
bs.reload();
|
|
377
|
+
});
|
|
378
|
+
}
|
|
358
379
|
|
|
359
380
|
}
|
|
360
381
|
|
|
361
382
|
// Build for production
|
|
362
|
-
if(!serve)
|
|
383
|
+
if(!serve && withDocs)
|
|
363
384
|
{
|
|
364
385
|
let result;
|
|
365
386
|
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
@use "mixins";
|
|
2
2
|
|
|
3
|
+
.zn-gutter {
|
|
4
|
+
margin: 0 var(--zn-gutter);
|
|
5
|
+
}
|
|
6
|
+
|
|
3
7
|
.zn-gap {
|
|
4
8
|
@include mixins.gap();
|
|
5
9
|
@include mixins.padding();
|
|
@@ -62,9 +66,16 @@
|
|
|
62
66
|
}
|
|
63
67
|
|
|
64
68
|
.form-spacing ~ .form-spacing {
|
|
65
|
-
margin-top: var(--zn-
|
|
69
|
+
margin-top: var(--zn-base-gap);
|
|
66
70
|
}
|
|
67
71
|
|
|
72
|
+
zn-form-group ~ zn-form-group {
|
|
73
|
+
margin-top: var(--zn-base-gap);
|
|
74
|
+
padding-top: var(--zn-base-gap);
|
|
75
|
+
border-top: 1px solid rgb(var(--zn-border-color));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
|
|
68
79
|
.form-spacing > * {
|
|
69
80
|
grid-column: span 6 / span 6;
|
|
70
81
|
}
|