@raylang/elements 0.0.0-stage → 0.3.0
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 +202 -0
- package/NOTICE +4 -0
- package/README.md +12 -2
- package/base.css +111 -0
- package/components/accordion/accordion.js +197 -0
- package/components/alert/alert.js +112 -0
- package/components/app-bar/app-bar.js +168 -0
- package/components/app-shell/app-shell.js +198 -0
- package/components/aspect-ratio/aspect-ratio.js +59 -0
- package/components/attachment/attachment.js +333 -0
- package/components/avatar/avatar.js +96 -0
- package/components/badge/badge.js +63 -0
- package/components/blockquote/blockquote.js +128 -0
- package/components/bottom-nav/bottom-nav.js +309 -0
- package/components/breadcrumbs/breadcrumbs.js +175 -0
- package/components/button/button.js +283 -0
- package/components/button-group/button-group.js +72 -0
- package/components/card/card.js +73 -0
- package/components/carousel/carousel.js +435 -0
- package/components/center/center.js +26 -0
- package/components/checkbox/checkbox.js +152 -0
- package/components/checkbox-group/checkbox-group.js +152 -0
- package/components/code/code.js +574 -0
- package/components/color-picker/color-picker.js +775 -0
- package/components/combobox/combobox.js +563 -0
- package/components/command-palette/command-palette.js +510 -0
- package/components/container/container.js +41 -0
- package/components/date-picker/date-picker.js +594 -0
- package/components/dialog/dialog.js +329 -0
- package/components/drawer/drawer.js +139 -0
- package/components/empty-state/empty-state.js +66 -0
- package/components/file-upload/file-upload.js +589 -0
- package/components/grid/grid.js +96 -0
- package/components/group/group.js +40 -0
- package/components/icon/icon.js +58 -0
- package/components/icon-button/icon-button.js +30 -0
- package/components/indicator/indicator.js +112 -0
- package/components/input/input.js +85 -0
- package/components/kbd/kbd.js +60 -0
- package/components/menu/menu.js +296 -0
- package/components/nav-link/nav-link.js +159 -0
- package/components/notification/notification.js +591 -0
- package/components/number-input/number-input.js +241 -0
- package/components/pagination/pagination.js +194 -0
- package/components/password-input/password-input.js +85 -0
- package/components/path-input/path-input.js +137 -0
- package/components/popover/popover.js +85 -0
- package/components/progress/progress.js +109 -0
- package/components/radio/radio.js +253 -0
- package/components/scroll-area/scroll-area.js +158 -0
- package/components/search/search.js +157 -0
- package/components/segmented-control/segmented-control.js +190 -0
- package/components/select/select.js +506 -0
- package/components/separator/separator.js +58 -0
- package/components/sidebar/sidebar.js +252 -0
- package/components/skeleton/skeleton.js +90 -0
- package/components/slider/slider.js +155 -0
- package/components/spinner/spinner.js +39 -0
- package/components/split/split.js +221 -0
- package/components/stack/stack.js +46 -0
- package/components/stat/stat.js +79 -0
- package/components/statusbar/statusbar.js +110 -0
- package/components/stepper/stepper.js +239 -0
- package/components/switch/switch.js +45 -0
- package/components/table/table.js +328 -0
- package/components/tabs/tabs.js +224 -0
- package/components/textarea/textarea.js +105 -0
- package/components/theme-toggle/theme-toggle.js +78 -0
- package/components/timeline/timeline.js +150 -0
- package/components/toggle/toggle.js +130 -0
- package/components/toggle-group/toggle-group.js +216 -0
- package/components/tooltip/tooltip.js +101 -0
- package/core/charts.js +107 -0
- package/core/color.js +110 -0
- package/core/core.js +556 -0
- package/core/dismiss.js +69 -0
- package/core/floating.js +195 -0
- package/core/focus.js +70 -0
- package/core/form.js +235 -0
- package/core/host.js +200 -0
- package/core/hotkey.js +40 -0
- package/core/icons.js +104 -0
- package/core/motion.js +73 -0
- package/core/position.js +91 -0
- package/core/raylang.js +167 -0
- package/core/scroll.js +58 -0
- package/core/styles.js +211 -0
- package/core.js +16 -0
- package/custom-elements.json +18545 -0
- package/index.js +74 -0
- package/package.json +312 -4
- package/ray-elements.d.ts +2570 -0
- package/tokens.css +796 -0
- package/tokens.json +2083 -0
- package/vscode.html-custom-data.json +5499 -0
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
// <ray-checkbox-group>: several choices among options (Mantine's
|
|
2
|
+
// Checkbox.Group), around ray-checkbox elements.
|
|
3
|
+
//
|
|
4
|
+
// The group is the form control: `value` is the array of the checked
|
|
5
|
+
// values, submitted as one entry each under `name` (like checkboxes that
|
|
6
|
+
// share a name). It stops its checkboxes' change and fires its own. `max`
|
|
7
|
+
// caps how many can be checked (the others are disabled meanwhile);
|
|
8
|
+
// `required` asks for at least one.
|
|
9
|
+
|
|
10
|
+
import { css, define } from "../../core/core.js";
|
|
11
|
+
import { sizeStyles } from "../../core/styles.js";
|
|
12
|
+
import { FormControl, fieldStyles } from "../../core/form.js";
|
|
13
|
+
|
|
14
|
+
const styles = css`
|
|
15
|
+
.items { display: flex; flex-direction: column; gap: var(--ray-space-3); margin-top: var(--ray-space-2); }
|
|
16
|
+
:host([orientation="horizontal"]) .items { flex-direction: row; flex-wrap: wrap; gap: var(--ray-space-3) var(--ray-space-5); }
|
|
17
|
+
.label { margin-bottom: 0; }
|
|
18
|
+
.count { margin-left: var(--ray-space-1); font-weight: 400; color: var(--ray-muted-foreground); font-variant-numeric: tabular-nums; }
|
|
19
|
+
`;
|
|
20
|
+
|
|
21
|
+
/** "a, b" (an attribute) or an array, as an array of values. */
|
|
22
|
+
const toList = (v) => (Array.isArray(v) ? v.map(String) : String(v ?? "").split(",").map((s) => s.trim()).filter(Boolean));
|
|
23
|
+
|
|
24
|
+
export class RayCheckboxGroup extends FormControl {
|
|
25
|
+
static delegatesFocus = false;
|
|
26
|
+
static properties = {
|
|
27
|
+
name: { type: String, reflect: true },
|
|
28
|
+
value: { attribute: false },
|
|
29
|
+
label: { type: String },
|
|
30
|
+
description: { type: String },
|
|
31
|
+
error: { type: String },
|
|
32
|
+
required: { type: Boolean, reflect: true },
|
|
33
|
+
disabled: { type: Boolean, reflect: true },
|
|
34
|
+
max: { type: Number },
|
|
35
|
+
orientation: { type: String, reflect: true, default: "vertical" },
|
|
36
|
+
size: { type: String, reflect: true },
|
|
37
|
+
color: { type: String, reflect: true },
|
|
38
|
+
descriptionPosition: { type: String, reflect: true, default: "above" },
|
|
39
|
+
};
|
|
40
|
+
static styles = [sizeStyles, fieldStyles, styles];
|
|
41
|
+
static template = `
|
|
42
|
+
<div class="label" part="label" id="label" hidden><span class="label-text"></span><span class="required" aria-hidden="true" hidden> *</span><span class="count" hidden></span></div>
|
|
43
|
+
<div class="description" part="description" id="description" hidden></div>
|
|
44
|
+
<div class="items" part="items"><slot></slot></div>
|
|
45
|
+
<div class="error" part="error" id="error" hidden></div>`;
|
|
46
|
+
|
|
47
|
+
static get observedAttributes() {
|
|
48
|
+
return [...super.observedAttributes, "value"];
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
attributeChangedCallback(attr, old, v) {
|
|
52
|
+
if (attr === "value") {
|
|
53
|
+
this.value = toList(v);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
super.attributeChangedCallback(attr, old, v);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
#default = null;
|
|
60
|
+
#own = new WeakMap();
|
|
61
|
+
|
|
62
|
+
constructor() {
|
|
63
|
+
super();
|
|
64
|
+
this.internals.role = "group";
|
|
65
|
+
// A checkbox's own change becomes the group's.
|
|
66
|
+
this.addEventListener("change", (e) => {
|
|
67
|
+
const box = e.target;
|
|
68
|
+
if (box === this || !this.checkboxes.includes(box)) return;
|
|
69
|
+
e.stopPropagation();
|
|
70
|
+
this.commitProperty("value", this.checkboxes.filter((c) => c.checked).map((c) => c.value));
|
|
71
|
+
this.dispatchEvent(new Event("input", { bubbles: true, composed: true }));
|
|
72
|
+
this.dispatchEvent(new Event("change", { bubbles: true }));
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
connectedCallback() {
|
|
77
|
+
super.connectedCallback();
|
|
78
|
+
if (!this._wired) {
|
|
79
|
+
this._wired = true;
|
|
80
|
+
this.$("slot").addEventListener("slotchange", () => this.requestUpdate());
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** The checkboxes of this group (direct or nested, not in a nested group). */
|
|
85
|
+
get checkboxes() {
|
|
86
|
+
return [...this.querySelectorAll("ray-checkbox")].filter((c) => c.closest("ray-checkbox-group") === this);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
update() {
|
|
90
|
+
const boxes = this.checkboxes;
|
|
91
|
+
// Without a value: the checkboxes marked checked in the markup.
|
|
92
|
+
if (this.value === undefined) {
|
|
93
|
+
this.commitProperty("value", boxes.filter((c) => c.hasAttribute("checked")).map((c) => c.value));
|
|
94
|
+
}
|
|
95
|
+
const value = toList(this.value);
|
|
96
|
+
this.#default ??= this.getAttribute("value") !== null ? toList(this.getAttribute("value")) : value.slice();
|
|
97
|
+
const disabled = this.effectivelyDisabled;
|
|
98
|
+
const full = this.max > 0 && value.length >= this.max;
|
|
99
|
+
for (const c of boxes) {
|
|
100
|
+
const on = value.includes(c.value);
|
|
101
|
+
if (c.checked !== on) c.checked = on;
|
|
102
|
+
// The group submits; the checkboxes only show.
|
|
103
|
+
if (c.hasAttribute("name")) c.removeAttribute("name");
|
|
104
|
+
if (this.size && !c.hasAttribute("size")) c.size = this.size;
|
|
105
|
+
if (this.color && !c.hasAttribute("color")) c.color = this.color;
|
|
106
|
+
// Its own disabled state, as the markup or a script set it before the group did.
|
|
107
|
+
if (!this.#own.has(c)) this.#own.set(c, Boolean(c.disabled));
|
|
108
|
+
const off = this.#own.get(c) || disabled || (full && !on);
|
|
109
|
+
if (Boolean(c.disabled) !== off) c.disabled = off;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
this.$("#label").hidden = !this.label;
|
|
113
|
+
this.$(".label-text").textContent = this.label ?? "";
|
|
114
|
+
this.$(".required").hidden = !this.required;
|
|
115
|
+
const count = this.$(".count");
|
|
116
|
+
count.hidden = !(this.max > 0);
|
|
117
|
+
count.textContent = this.max > 0 ? `${value.length} / ${this.max}` : "";
|
|
118
|
+
const desc = this.$("#description");
|
|
119
|
+
desc.hidden = !this.description;
|
|
120
|
+
desc.textContent = this.description ?? "";
|
|
121
|
+
const err = this.$("#error");
|
|
122
|
+
err.hidden = !this.error;
|
|
123
|
+
err.textContent = this.error ?? "";
|
|
124
|
+
this.internals.ariaLabel = this.label || this.getAttribute("aria-label") || null;
|
|
125
|
+
this.internals.ariaDisabled = disabled ? "true" : "false";
|
|
126
|
+
this.internals.ariaInvalid = this.error ? "true" : "false";
|
|
127
|
+
this.internals.ariaDescription = [this.description, this.error].filter(Boolean).join(". ") || null;
|
|
128
|
+
|
|
129
|
+
if (this.name && value.length) {
|
|
130
|
+
const data = new FormData();
|
|
131
|
+
for (const v of value) data.append(this.name, v);
|
|
132
|
+
this.internals.setFormValue(data);
|
|
133
|
+
} else {
|
|
134
|
+
this.internals.setFormValue(null);
|
|
135
|
+
}
|
|
136
|
+
if (this.required && !value.length) {
|
|
137
|
+
this.internals.setValidity({ valueMissing: true }, "Please select at least one option.", boxes[0] ?? undefined);
|
|
138
|
+
} else {
|
|
139
|
+
this.internals.setValidity({});
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
formResetCallback() {
|
|
144
|
+
this.value = (this.#default ?? []).slice();
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
formStateRestoreCallback(state) {
|
|
148
|
+
if (state instanceof FormData) this.value = state.getAll(this.name).map(String);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
define("ray-checkbox-group", RayCheckboxGroup);
|