@ixfx/components 0.5.0 → 0.5.2
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/bundle/index.d.ts +68 -2
- package/bundle/index.d.ts.map +1 -1
- package/bundle/index.js +184 -5
- package/bundle/index.js.map +1 -1
- package/bundle/style.css +80 -0
- package/dist/{button-DxYee1ZH.js → button-CTE8crYn.js} +3 -1
- package/dist/button-CTE8crYn.js.map +1 -0
- package/dist/button.js +1 -1
- package/dist/index.d.ts +68 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +183 -6
- package/dist/index.js.map +1 -1
- package/dist/style.css +80 -0
- package/docs-user/README.md +1 -0
- package/docs-user/button.md +2 -0
- package/docs-user/form.md +108 -0
- package/docs-user/tabs.md +51 -2
- package/docs-user/vertical-list.md +29 -2
- package/package.json +1 -1
- package/dist/button-DxYee1ZH.js.map +0 -1
package/dist/style.css
CHANGED
|
@@ -141,3 +141,83 @@
|
|
|
141
141
|
ixfx-grouped-item-lister {
|
|
142
142
|
display: block;
|
|
143
143
|
}
|
|
144
|
+
ixfx-form {
|
|
145
|
+
display: block;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
ixfx-form-group {
|
|
149
|
+
display: block;
|
|
150
|
+
container-type: inline-size;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
ixfx-form-group fieldset {
|
|
154
|
+
gap: var(--space-m) var(--space-l);
|
|
155
|
+
margin: 0;
|
|
156
|
+
border: 0;
|
|
157
|
+
grid-template-columns: 1fr;
|
|
158
|
+
min-inline-size: 0;
|
|
159
|
+
margin-block-start: var(--space-m);
|
|
160
|
+
margin-block-end: var(--space-m);
|
|
161
|
+
padding: 0;
|
|
162
|
+
display: grid;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
ixfx-form-group fieldset > legend:empty {
|
|
166
|
+
display: none;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
ixfx-form-group fieldset > legend {
|
|
170
|
+
font-weight: var(--font-weight-bold);
|
|
171
|
+
grid-column: 1 / -1;
|
|
172
|
+
margin-block-start: var(--space-m);
|
|
173
|
+
margin-block-end: var(--space-s);
|
|
174
|
+
padding: 0;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
ixfx-form-group fieldset > :not(ixfx-form-part) {
|
|
178
|
+
grid-column: 1 / -1;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
ixfx-form-part {
|
|
182
|
+
grid-column: 1 / -1;
|
|
183
|
+
grid-template-columns: 1fr;
|
|
184
|
+
align-items: start;
|
|
185
|
+
display: grid;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
ixfx-form-part > label {
|
|
189
|
+
font-size: var(--ixfx-form-label-font-size, var(--text-s));
|
|
190
|
+
font-weight: var(--ixfx-form-label-font-weight, inherit);
|
|
191
|
+
font-family: var(--ixfx-form-label-font-family, inherit);
|
|
192
|
+
color: var(--ixfx-form-label-color, inherit);
|
|
193
|
+
text-transform: var(--ixfx-form-label-text-transform, uppercase);
|
|
194
|
+
padding-bottom: var(--space-xs);
|
|
195
|
+
grid-area: 1 / 1;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
ixfx-form-part > input, ixfx-form-part > select, ixfx-form-part > textarea {
|
|
199
|
+
grid-area: 2 / 1;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
@container (width >= 30rem) {
|
|
203
|
+
ixfx-form-group fieldset {
|
|
204
|
+
grid-template-columns: max-content 1fr;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
ixfx-form-part {
|
|
208
|
+
grid-column: 1 / -1;
|
|
209
|
+
grid-template-columns: subgrid;
|
|
210
|
+
align-items: baseline;
|
|
211
|
+
display: grid;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
ixfx-form-part > label {
|
|
215
|
+
padding-right: var(--space-xs);
|
|
216
|
+
grid-area: 1 / 1;
|
|
217
|
+
padding-bottom: 0;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
ixfx-form-part > input, ixfx-form-part > select, ixfx-form-part > textarea {
|
|
221
|
+
grid-area: 1 / 2;
|
|
222
|
+
}
|
|
223
|
+
}
|
package/docs-user/README.md
CHANGED
|
@@ -12,6 +12,7 @@ This directory contains documentation for each component and some architectural
|
|
|
12
12
|
- [crumbs](./crumbs.md)
|
|
13
13
|
- [data-display](./data-display.md)
|
|
14
14
|
- [editable-label](./editable-label.md)
|
|
15
|
+
- [form](./form.md)
|
|
15
16
|
- [grouped-item-lister](./grouped-item-lister.md)
|
|
16
17
|
- [icons](./icons.md)
|
|
17
18
|
- [incr-search](./incr-search.md)
|
package/docs-user/button.md
CHANGED
|
@@ -66,6 +66,8 @@ btn.icon = '<svg viewBox="0 0 24 24" fill="currentColor"><path d="..."/></svg>';
|
|
|
66
66
|
| `--disabled-opacity`| `0.5` | Opacity when disabled |
|
|
67
67
|
| `--ixfx-button-hide-icon` | `inline-flex` (icon shown) | Set to `none` to hide the icon. Overridden by the `hide-icon` attribute. |
|
|
68
68
|
| `--ixfx-button-hide-label` | `inline` (label shown) | Set to `none` to hide the label. Overridden by the `hide-label` attribute. |
|
|
69
|
+
| `--ixfx-button-outline` | `none` | Additional outline around the button (e.g. `2px solid var(--accent)`) |
|
|
70
|
+
| `--ixfx-button-shade` | `none` | Tinted overlay via box-shadow (e.g. `inset 0 0 8px 2px color-mix(in oklch, red 35%, transparent)`) |
|
|
69
71
|
|
|
70
72
|
`--ixfx-button-hide-icon`/`--ixfx-button-hide-label` let you hide the icon/label conditionally from plain CSS — handy for a media or container query — without touching the `hide-icon`/`hide-label` attributes:
|
|
71
73
|
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# Form layout components
|
|
2
|
+
|
|
3
|
+
Primitives for typical form layout with responsive label positioning and data binding.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## `ixfx-form`
|
|
8
|
+
|
|
9
|
+
Main container for form sections. Provides `getValues()` and `setValues()` methods for data binding.
|
|
10
|
+
|
|
11
|
+
```html
|
|
12
|
+
<ixfx-form>
|
|
13
|
+
<ixfx-form-group label="Section A">
|
|
14
|
+
<p>Preamble text for section A...</p>
|
|
15
|
+
<ixfx-form-part label="Some text">
|
|
16
|
+
<input type="text" name="input1" />
|
|
17
|
+
</ixfx-form-part>
|
|
18
|
+
<ixfx-form-part label="Some other text">
|
|
19
|
+
<input type="text" name="input2" />
|
|
20
|
+
</ixfx-form-part>
|
|
21
|
+
</ixfx-form-group>
|
|
22
|
+
</ixfx-form>
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Properties / attributes
|
|
26
|
+
|
|
27
|
+
`ixfx-form` has no attributes — it is a pure layout and data-binding container.
|
|
28
|
+
|
|
29
|
+
### Methods
|
|
30
|
+
|
|
31
|
+
| Method | Returns | Description |
|
|
32
|
+
|--------|---------|-------------|
|
|
33
|
+
| `getValues()` | `Record<string, unknown>` | Collects values from all named inputs within the form |
|
|
34
|
+
| `setValues(data)` | `void` | Applies values to named inputs. Keys absent from `data` are left untouched. |
|
|
35
|
+
|
|
36
|
+
### Value collection rules
|
|
37
|
+
|
|
38
|
+
- Native `<input type=radio>` sharing a `name` → value of the checked one
|
|
39
|
+
- Native/checked-bearing checkbox → boolean
|
|
40
|
+
- `<select multiple>` → array of selected values
|
|
41
|
+
- Everything else with a `.value` property → used as-is
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## `ixfx-form-group`
|
|
46
|
+
|
|
47
|
+
A section within the form, backed by a `<fieldset>`/`<legend>` for proper accessibility semantics.
|
|
48
|
+
|
|
49
|
+
```html
|
|
50
|
+
<ixfx-form-group label="Personal Information">
|
|
51
|
+
<ixfx-form-part label="Full Name">
|
|
52
|
+
<input type="text" name="name" />
|
|
53
|
+
</ixfx-form-part>
|
|
54
|
+
<ixfx-form-part label="Email">
|
|
55
|
+
<input type="email" name="email" />
|
|
56
|
+
</ixfx-form-part>
|
|
57
|
+
</ixfx-form-group>
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Properties / attributes
|
|
61
|
+
|
|
62
|
+
| Attribute / Property | Type | Default | Description |
|
|
63
|
+
|---------------------|--------|---------|-------------|
|
|
64
|
+
| `label` | string | `''` | Section heading text |
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## `ixfx-form-part`
|
|
69
|
+
|
|
70
|
+
Wraps a form control with a label. Uses light DOM so the `<label for>` natively associates with the slotted input.
|
|
71
|
+
|
|
72
|
+
```html
|
|
73
|
+
<ixfx-form-part label="Username">
|
|
74
|
+
<input type="text" name="username" />
|
|
75
|
+
</ixfx-form-part>
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Properties / attributes
|
|
79
|
+
|
|
80
|
+
| Attribute / Property | Type | Default | Description |
|
|
81
|
+
|---------------------|--------|---------|-------------|
|
|
82
|
+
| `label` | string | `''` | Label text displayed for the control |
|
|
83
|
+
|
|
84
|
+
### How it works
|
|
85
|
+
|
|
86
|
+
`ixfx-form-part` generates an `<label for="...">` element that is associated with the first control-like child (`<input>`, `<select>`, `<textarea>`, or element with a `name` attribute). The association works natively because both elements live in the same light DOM tree — no shadow boundary to work around.
|
|
87
|
+
|
|
88
|
+
An `id` is generated for the control if it doesn't already have one.
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Responsive behaviour
|
|
93
|
+
|
|
94
|
+
The layout switches between two modes based on available width (via CSS container queries):
|
|
95
|
+
|
|
96
|
+
**Narrow (< 30rem):** Label appears above the input, single-column stacked layout.
|
|
97
|
+
|
|
98
|
+
**Wide (≥ 30rem):** Label appears to the left of the input, two-column grid. All labels in a group share the width of the widest label (right-justified).
|
|
99
|
+
|
|
100
|
+
Resize the container to see the transition.
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## TypeScript types
|
|
105
|
+
|
|
106
|
+
```ts
|
|
107
|
+
import type { FormElement, FormGroupElement, FormPartElement } from 'ixfxfun-components';
|
|
108
|
+
```
|
package/docs-user/tabs.md
CHANGED
|
@@ -27,10 +27,18 @@ Wire them together:
|
|
|
27
27
|
const tabList = document.querySelector('ixfx-tab-list');
|
|
28
28
|
const tabPanels = document.querySelector('ixfx-tab-panels');
|
|
29
29
|
tabList.addEventListener('change', e => {
|
|
30
|
-
tabPanels.selectPanel(e.detail.
|
|
30
|
+
tabPanels.selectPanel(e.detail.for);
|
|
31
31
|
});
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
+
Select a tab programmatically — same effect as clicking it (header + content):
|
|
35
|
+
|
|
36
|
+
```js
|
|
37
|
+
tabPanels.syncWithList(tabList);
|
|
38
|
+
tabPanels.selectTab('Home'); // by label text
|
|
39
|
+
tabPanels.selectTab('panel-home'); // by the panel id a tab's `for` points at
|
|
40
|
+
```
|
|
41
|
+
|
|
34
42
|
---
|
|
35
43
|
|
|
36
44
|
## `ixfx-tab-list`
|
|
@@ -167,6 +175,46 @@ A recommended `.tab-toolbar-btn` style for the page stylesheet:
|
|
|
167
175
|
|----------|--------|----------------------------|
|
|
168
176
|
| `close` | — | Fired when close button clicked; item removes itself from DOM |
|
|
169
177
|
|
|
178
|
+
### Command activation
|
|
179
|
+
|
|
180
|
+
Tabs can be programmatically activated via the `CommandRegistry` system. This is useful for keyboard shortcuts (e.g. `Alt+1` to switch to tab 1).
|
|
181
|
+
|
|
182
|
+
1. Create a `CommandRegistry` and register commands for each tab:
|
|
183
|
+
```js
|
|
184
|
+
import { CommandRegistry } from '@clinth/ui-commands';
|
|
185
|
+
|
|
186
|
+
const commands = new CommandRegistry();
|
|
187
|
+
commands.register({ id: 'tab-home', label: 'Home', description: 'Switch to Home tab', execute: () => {} });
|
|
188
|
+
commands.register({ id: 'tab-profile', label: 'Profile', description: 'Switch to Profile tab', execute: () => {} });
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
2. Bind keyboard shortcuts to the commands using `KeyboardManager`:
|
|
192
|
+
```js
|
|
193
|
+
import { KeyboardManager } from '@clinth/ui-commands';
|
|
194
|
+
|
|
195
|
+
const keyboard = new KeyboardManager();
|
|
196
|
+
keyboard.bind({ key: '1', modifiers: new Set(['alt']), commandId: 'tab-home' });
|
|
197
|
+
keyboard.bind({ key: '2', modifiers: new Set(['alt']), commandId: 'tab-profile' });
|
|
198
|
+
keyboard.onKeyEvent((commandId) => commands.invoke(commandId));
|
|
199
|
+
keyboard.attach(document.body);
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
3. Set the `command-active` attribute and assign the registry to each tab item:
|
|
203
|
+
```html
|
|
204
|
+
<ixfx-tab-list>
|
|
205
|
+
<ixfx-tab-list-item command-active="tab-home">Home</ixfx-tab-list-item>
|
|
206
|
+
<ixfx-tab-list-item command-active="tab-profile">Profile</ixfx-tab-list-item>
|
|
207
|
+
</ixfx-tab-list>
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
```js
|
|
211
|
+
for (const item of document.querySelectorAll('ixfx-tab-list-item[command-active]')) {
|
|
212
|
+
item.registry = commands;
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
When a command is invoked (via keyboard shortcut or `commands.invoke('tab-home')`), the associated tab will be activated as if clicked.
|
|
217
|
+
|
|
170
218
|
### CSS custom properties
|
|
171
219
|
|
|
172
220
|
| Property | Default | Description |
|
|
@@ -212,4 +260,5 @@ Manages multiple `ixfx-tab-panel` children, selecting one at a time.
|
|
|
212
260
|
|---------------------|----------|---------|----------------------------------|
|
|
213
261
|
| `getSelectedElement()` | — | `TabPanelElement \| undefined` | Get currently selected panel |
|
|
214
262
|
| `selectPanel(id)` | `string` | `boolean` | Select panel by ID; returns true if found |
|
|
215
|
-
| `
|
|
263
|
+
| `selectTab(nameOrTitle)` | `string` | `boolean` | Select a tab as if it was clicked: activates the matching header (via the list associated with `syncWithList`) and shows its panel. `nameOrTitle` can be a tab's label text (case-insensitive) or the panel id its `for` attribute points at. Returns true if a panel was found |
|
|
264
|
+
| `syncWithList(el)` | `TabListElement` | `void` | Associates this panels element with a tab list, syncing panel selection to it. Must be called before `selectTab()` if the tab header should be activated |
|
|
@@ -116,7 +116,7 @@ To reflect selection state inside the custom element's shadow DOM, target the `:
|
|
|
116
116
|
| `selectionMode` / `selection-mode` | `'none' \| 'single' \| 'multiple'` | `'single'` | Which items can be selected simultaneously |
|
|
117
117
|
| `interactionMode` / `interaction-mode` | `ListInteractionMode` | `'standard'` | How gestures map to selection changes (see table below) |
|
|
118
118
|
| `filterPredicate` | `((el: Element) => boolean) \| undefined` | `undefined` | External filter; only items returning `true` are shown |
|
|
119
|
-
| `checkboxRenderer` | `((checked: boolean) => unknown) \| undefined` | `undefined` | Custom content for the checkbox in `checked` mode. See [Custom checkbox](#custom-checkbox) |
|
|
119
|
+
| `checkboxRenderer` | `((checked: boolean) => unknown) \| CustomCheckboxOptions \| undefined` | `undefined` | Custom content for the checkbox in `checked` mode. See [Custom checkbox](#custom-checkbox) |
|
|
120
120
|
|
|
121
121
|
Switching `interactionMode` always clears the current selection.
|
|
122
122
|
|
|
@@ -140,7 +140,7 @@ By default the column contains a native `<input type="checkbox">`. The visible s
|
|
|
140
140
|
|
|
141
141
|
### Subtle style — `checkboxRenderer`
|
|
142
142
|
|
|
143
|
-
Set `checkboxRenderer` to a function that returns a Lit template. The function receives the row's current `checked` state. This is what enables the *subtle* style: render an empty template when unchecked and a translucent mark when checked.
|
|
143
|
+
Set `checkboxRenderer` to a function that returns a Lit template, or pass an options object for additional control. The function receives the row's current `checked` state. This is what enables the *subtle* style: render an empty template when unchecked and a translucent mark when checked.
|
|
144
144
|
|
|
145
145
|
```typescript
|
|
146
146
|
import { html } from 'lit';
|
|
@@ -160,6 +160,33 @@ list.checkboxRenderer = (checked) => checked
|
|
|
160
160
|
: html``;
|
|
161
161
|
```
|
|
162
162
|
|
|
163
|
+
#### Using `CustomCheckboxOptions`
|
|
164
|
+
|
|
165
|
+
Pass an options object to also control the checkbox column's `margin` and `width`:
|
|
166
|
+
|
|
167
|
+
```typescript
|
|
168
|
+
import type { CustomCheckboxOptions } from '@ixfx/components';
|
|
169
|
+
|
|
170
|
+
list.checkboxRenderer = {
|
|
171
|
+
renderer: (checked) => checked
|
|
172
|
+
? html`<svg viewBox="0 0 16 16" width="14" height="14"
|
|
173
|
+
fill="none" stroke="currentColor" stroke-width="2"
|
|
174
|
+
stroke-linecap="round" stroke-linejoin="round"
|
|
175
|
+
style="opacity:0.5">
|
|
176
|
+
<polyline points="3,8 7,12 13,4" />
|
|
177
|
+
</svg>`
|
|
178
|
+
: html``,
|
|
179
|
+
margin: `0 6px 0 0`, // left margin for the checkbox column (default: `0`)
|
|
180
|
+
width: `24px`, // width of the checkbox column (default: `24px`)
|
|
181
|
+
} satisfies CustomCheckboxOptions;
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
| Option | Type | Default | Description |
|
|
185
|
+
|---|---|---|---|
|
|
186
|
+
| `renderer` | `(checked: boolean) => unknown` | — | Required. Returns the Lit template to render inside the checkbox cell |
|
|
187
|
+
| `margin` | `string` | `0` | CSS margin for the checkbox column (e.g. `"0 6px 0 0"`) |
|
|
188
|
+
| `width` | `string` | `24px` | Width of the checkbox column |
|
|
189
|
+
|
|
163
190
|
Because the wrapper still spans the full row height and owns the click handler, the empty unchecked area is just as clickable as the visible tick — even though there is no border, background, or other visual indicator of where the column is.
|
|
164
191
|
|
|
165
192
|
### How it works under the hood
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"button-DxYee1ZH.js","names":["customElement"],"sources":["../src/button/button-styles.ts","../src/button/button.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const buttonStyles = css`\n :host {\n display: inline-flex;\n max-width: 100%;\n vertical-align: middle;\n user-select: none;\n -webkit-user-select: none;\n }\n\n button {\n cursor: pointer;\n appearance: none;\n background: var(--surface-4, #ccc);\n color: var(--surface-3-text, #000);\n border: var(--border, 1px solid #999);\n border-radius: var(--radius-xl, 8px);\n corner-shape: superellipse(1);\n padding: var(--space-m, 8px) var(--space-l, 12px);\n font-family: var(--font-family, inherit);\n font-size: var(--text-m, 14px);\n margin: 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.5em;\n width: 100%;\n overflow: hidden;\n white-space: nowrap;\n box-shadow: \n inset 1px 1px 1px 1px color-mix(in oklch, var(--surface-4) 30%, transparent), inset -1px -1px 1px 1px color-mix(in oklch, var(--surface-2) 20%, transparent),\n 2px 2px 1px 0px color-mix(in oklch, var(--surface-2) 30%, transparent);\n transition: background var(--transition, 0.2s), border-color var(--transition, 0.2s);\n }\n\n button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n button:hover:not(:disabled) {\n background: color-mix(in oklch, var(--surface-4) 80%, transparent);\n border-color: var(--accent, #666);\n box-shadow: \n inset 1px 1px 1px 1px color-mix(in oklch, var(--surface-5) 70%, transparent), \n inset -1px -1px 1px 1px color-mix(in oklch, var(--surface-2) 60%, transparent),\n 2px 2px 1px 0px color-mix(in oklch, var(--surface-2) 90%, transparent);\n }\n\n button:active:not(:disabled) {\n background: var(--surface-2, #aaa);\n transform: translateY(1px);\n box-shadow: inset 1px 1px 0px 0.5px color-mix(in oklch,var(--surface-1),transparent);\n }\n\n .button-icon {\n display: var(--ixfx-button-hide-icon, inline-flex);\n align-items: center;\n flex-shrink: 0;\n }\n\n .button-label {\n white-space: nowrap;\n display: var(--ixfx-button-hide-label, inline);\n }\n\n :host([hide-label]) .button-label {\n display: none;\n }\n\n :host([hide-icon]) .button-icon {\n display: none;\n }\n`;\n","import { html, LitElement, nothing } from \"lit\";\nimport { property } from \"lit/decorators.js\";\nimport { unsafeHTML } from \"lit/directives/unsafe-html.js\";\nimport { getIcon } from \"../icons/index.js\";\nimport { prominenceStyles } from \"../styles/prominence.js\";\nimport { safeCustomElement as customElement } from \"../util/custom-elements.js\";\nimport { buttonStyles } from \"./button-styles.js\";\n\n@customElement(`ixfx-button`)\nexport class ButtonElement extends LitElement {\n @property({ type: Boolean })\n disabled = false;\n\n @property({ type: String })\n icon?: string;\n\n @property({ type: Boolean, attribute: `hide-icon`, reflect: true })\n hideIcon = false;\n\n @property({ type: Boolean, attribute: `hide-label`, reflect: true })\n hideLabel = false;\n\n protected _renderIcon() {\n if (this.hideIcon || !this.icon)\n return nothing;\n\n if (this.icon.startsWith(`<svg`)) {\n return html`<span class=\"button-icon\">${unsafeHTML(this.icon)}</span>`;\n }\n\n const svg = getIcon(this.icon);\n\n if (!svg)\n return nothing;\n\n return html`<ixfx-icon class=\"button-icon\" name=\"${this.icon}\"></ixfx-icon>`;\n }\n\n protected render() {\n const label = this.hideLabel\n ? nothing\n : html`<span class=\"button-label\"><slot></slot></span>`;\n return html`<button ?disabled=${this.disabled}>${this._renderIcon()}${label}</button>`;\n }\n\n static styles = [\n prominenceStyles,\n buttonStyles,\n ];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"ixfx-button\": ButtonElement;\n }\n}\n"],"mappings":";;;;;;;;AAEA,MAAa,eAAe,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACOxB,IAAM,gBAAN,MAAM,sBAAsB,WAAW;;;EAEjC,KAAA,WAAA;EAMA,KAAA,WAAA;EAGC,KAAA,YAAA;;CAEZ,cAAwB;EACtB,IAAI,KAAK,YAAY,CAAC,KAAK,MACzB,OAAO;EAET,IAAI,KAAK,KAAK,WAAW,MAAM,GAC7B,OAAO,IAAI,6BAA6B,WAAW,KAAK,IAAI,EAAE;EAKhE,IAAI,CAFQ,QAAQ,KAAK,IAElB,GACL,OAAO;EAET,OAAO,IAAI,wCAAwC,KAAK,KAAK;CAC/D;CAEA,SAAmB;EACjB,MAAM,QAAQ,KAAK,YACf,UACA,IAAI;EACR,OAAO,IAAI,qBAAqB,KAAK,SAAS,GAAG,KAAK,YAAY,IAAI,MAAM;CAC9E;;EAEgB,KAAA,SAAA,CACd,kBACA,YACF;;AACF;AAvCG,WAAA,CAAA,SAAS,EAAE,MAAM,QAAQ,CAAC,CAAA,GAAA,cAAA,WAAA,YAAA,KAAA,CAAA;AAG1B,WAAA,CAAA,SAAS,EAAE,MAAM,OAAO,CAAC,CAAA,GAAA,cAAA,WAAA,QAAA,KAAA,CAAA;AAGzB,WAAA,CAAA,SAAS;CAAE,MAAM;CAAS,WAAW;CAAa,SAAS;AAAK,CAAC,CAAA,GAAA,cAAA,WAAA,YAAA,KAAA,CAAA;AAGjE,WAAA,CAAA,SAAS;CAAE,MAAM;CAAS,WAAW;CAAc,SAAS;AAAK,CAAC,CAAA,GAAA,cAAA,WAAA,aAAA,KAAA,CAAA;AAXpEA,gBAAAA,WAAAA,CAAAA,kBAAc,aAAa,CAAA,GAAA,aAAA"}
|