@livenetworks/ashlar 1.3.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/README.md +177 -0
- package/js/COMPONENTS.md +1102 -0
- package/js/index.js +41 -0
- package/js/ln-accordion/README.md +137 -0
- package/js/ln-accordion/ln-accordion.js +1 -0
- package/js/ln-accordion/src/ln-accordion.js +41 -0
- package/js/ln-ajax/README.md +91 -0
- package/js/ln-ajax/ln-ajax.js +1 -0
- package/js/ln-ajax/src/ln-ajax.js +277 -0
- package/js/ln-api-connector/README.md +150 -0
- package/js/ln-api-connector/ln-api-connector.js +1 -0
- package/js/ln-api-connector/src/ln-api-connector.js +265 -0
- package/js/ln-autoresize/README.md +80 -0
- package/js/ln-autoresize/ln-autoresize.js +1 -0
- package/js/ln-autoresize/src/ln-autoresize.js +47 -0
- package/js/ln-autosave/README.md +92 -0
- package/js/ln-autosave/ln-autosave.js +1 -0
- package/js/ln-autosave/src/ln-autosave.js +147 -0
- package/js/ln-circular-progress/README.md +161 -0
- package/js/ln-circular-progress/ln-circular-progress.js +1 -0
- package/js/ln-circular-progress/src/ln-circular-progress.js +133 -0
- package/js/ln-confirm/README.md +86 -0
- package/js/ln-confirm/_ln-confirm.scss +13 -0
- package/js/ln-confirm/ln-confirm.js +1 -0
- package/js/ln-confirm/src/ln-confirm.js +131 -0
- package/js/ln-core/crypto.js +83 -0
- package/js/ln-core/helpers.js +411 -0
- package/js/ln-core/index.js +5 -0
- package/js/ln-core/persist.js +71 -0
- package/js/ln-core/positioning.js +207 -0
- package/js/ln-core/reactive.js +74 -0
- package/js/ln-couchdb-connector/README.md +156 -0
- package/js/ln-couchdb-connector/ln-couchdb-connector.js +1 -0
- package/js/ln-couchdb-connector/src/ln-couchdb-connector.js +348 -0
- package/js/ln-data-coordinator/README.md +165 -0
- package/js/ln-data-coordinator/ln-data-coordinator.js +1 -0
- package/js/ln-data-coordinator/src/ln-data-coordinator.js +249 -0
- package/js/ln-data-store/README.md +94 -0
- package/js/ln-data-store/ln-data-store.js +1 -0
- package/js/ln-data-store/src/ln-data-store.js +699 -0
- package/js/ln-data-table/README.md +110 -0
- package/js/ln-data-table/ln-data-table.js +1 -0
- package/js/ln-data-table/ln-data-table.scss +10 -0
- package/js/ln-data-table/src/ln-data-table.js +1103 -0
- package/js/ln-date/README.md +151 -0
- package/js/ln-date/ln-date.js +1 -0
- package/js/ln-date/src/ln-date.js +442 -0
- package/js/ln-dropdown/README.md +117 -0
- package/js/ln-dropdown/ln-dropdown.js +1 -0
- package/js/ln-dropdown/ln-dropdown.scss +15 -0
- package/js/ln-dropdown/src/ln-dropdown.js +174 -0
- package/js/ln-external-links/README.md +341 -0
- package/js/ln-external-links/ln-external-links.js +1 -0
- package/js/ln-external-links/src/ln-external-links.js +116 -0
- package/js/ln-filter/README.md +99 -0
- package/js/ln-filter/ln-filter.js +1 -0
- package/js/ln-filter/ln-filter.scss +7 -0
- package/js/ln-filter/src/ln-filter.js +404 -0
- package/js/ln-form/README.md +101 -0
- package/js/ln-form/ln-form.js +1 -0
- package/js/ln-form/src/ln-form.js +199 -0
- package/js/ln-http/README.md +89 -0
- package/js/ln-http/ln-http.js +1 -0
- package/js/ln-http/src/ln-http.js +219 -0
- package/js/ln-icons/README.md +88 -0
- package/js/ln-icons/ln-icons.js +1 -0
- package/js/ln-icons/src/ln-icons.js +169 -0
- package/js/ln-link/README.md +303 -0
- package/js/ln-link/ln-link.js +1 -0
- package/js/ln-link/src/ln-link.js +196 -0
- package/js/ln-modal/README.md +154 -0
- package/js/ln-modal/ln-modal.js +1 -0
- package/js/ln-modal/ln-modal.scss +11 -0
- package/js/ln-modal/src/ln-modal.js +201 -0
- package/js/ln-nav/README.md +70 -0
- package/js/ln-nav/ln-nav.js +1 -0
- package/js/ln-nav/src/ln-nav.js +177 -0
- package/js/ln-number/README.md +122 -0
- package/js/ln-number/ln-number.js +1 -0
- package/js/ln-number/src/ln-number.js +302 -0
- package/js/ln-popover/README.md +127 -0
- package/js/ln-popover/ln-popover.js +1 -0
- package/js/ln-popover/src/ln-popover.js +288 -0
- package/js/ln-progress/README.md +442 -0
- package/js/ln-progress/ln-progress.js +1 -0
- package/js/ln-progress/src/ln-progress.js +150 -0
- package/js/ln-search/README.md +83 -0
- package/js/ln-search/ln-search.js +1 -0
- package/js/ln-search/ln-search.scss +7 -0
- package/js/ln-search/src/ln-search.js +114 -0
- package/js/ln-sortable/README.md +95 -0
- package/js/ln-sortable/ln-sortable.js +1 -0
- package/js/ln-sortable/src/ln-sortable.js +203 -0
- package/js/ln-table/README.md +101 -0
- package/js/ln-table/ln-table-sort.js +1 -0
- package/js/ln-table/ln-table.js +1 -0
- package/js/ln-table/ln-table.scss +11 -0
- package/js/ln-table/src/ln-table-sort.js +168 -0
- package/js/ln-table/src/ln-table.js +473 -0
- package/js/ln-tabs/README.md +137 -0
- package/js/ln-tabs/ln-tabs.js +1 -0
- package/js/ln-tabs/src/ln-tabs.js +171 -0
- package/js/ln-time/README.md +81 -0
- package/js/ln-time/ln-time.js +1 -0
- package/js/ln-time/src/ln-time.js +192 -0
- package/js/ln-toast/README.md +122 -0
- package/js/ln-toast/ln-toast.js +15 -0
- package/js/ln-toast/src/ln-toast.js +210 -0
- package/js/ln-toast/template.html +14 -0
- package/js/ln-toggle/README.md +137 -0
- package/js/ln-toggle/ln-toggle.js +1 -0
- package/js/ln-toggle/src/ln-toggle.js +139 -0
- package/js/ln-tooltip/README.md +58 -0
- package/js/ln-tooltip/ln-tooltip.js +1 -0
- package/js/ln-tooltip/ln-tooltip.scss +9 -0
- package/js/ln-tooltip/src/ln-tooltip.js +169 -0
- package/js/ln-translations/README.md +96 -0
- package/js/ln-translations/ln-translations.js +1 -0
- package/js/ln-translations/src/ln-translations.js +275 -0
- package/js/ln-upload/README.md +180 -0
- package/js/ln-upload/ln-upload.js +1 -0
- package/js/ln-upload/ln-upload.scss +20 -0
- package/js/ln-upload/src/ln-upload.js +407 -0
- package/js/ln-validate/README.md +108 -0
- package/js/ln-validate/ln-validate.js +1 -0
- package/js/ln-validate/src/ln-validate.js +160 -0
- package/package.json +55 -0
- package/scss/base/_global.scss +83 -0
- package/scss/base/_reset.scss +17 -0
- package/scss/base/_typography.scss +125 -0
- package/scss/components/_accordion.scss +34 -0
- package/scss/components/_ajax.scss +15 -0
- package/scss/components/_alert.scss +5 -0
- package/scss/components/_app-shell.scss +15 -0
- package/scss/components/_avatar.scss +6 -0
- package/scss/components/_breadcrumbs.scss +33 -0
- package/scss/components/_button.scss +20 -0
- package/scss/components/_card.scss +10 -0
- package/scss/components/_chip.scss +5 -0
- package/scss/components/_circular-progress.scss +29 -0
- package/scss/components/_confirm.scss +5 -0
- package/scss/components/_data-table.scss +83 -0
- package/scss/components/_dropdown.scss +25 -0
- package/scss/components/_empty-state.scss +22 -0
- package/scss/components/_form.scss +100 -0
- package/scss/components/_layout.scss +8 -0
- package/scss/components/_link.scss +11 -0
- package/scss/components/_ln-table.scss +60 -0
- package/scss/components/_loader.scss +6 -0
- package/scss/components/_modal.scss +20 -0
- package/scss/components/_nav.scss +9 -0
- package/scss/components/_page-header.scss +10 -0
- package/scss/components/_popover.scss +10 -0
- package/scss/components/_progress.scss +17 -0
- package/scss/components/_prose.scss +5 -0
- package/scss/components/_scrollbar.scss +32 -0
- package/scss/components/_sections.scss +12 -0
- package/scss/components/_sidebar.scss +5 -0
- package/scss/components/_stat-card.scss +5 -0
- package/scss/components/_status-badge.scss +4 -0
- package/scss/components/_stepper.scss +5 -0
- package/scss/components/_table.scss +19 -0
- package/scss/components/_tabs.scss +21 -0
- package/scss/components/_timeline.scss +14 -0
- package/scss/components/_toast.scss +41 -0
- package/scss/components/_toggle.scss +81 -0
- package/scss/components/_tooltip.scss +18 -0
- package/scss/components/_translations.scss +111 -0
- package/scss/components/_upload.scss +51 -0
- package/scss/config/_breakpoints.scss +72 -0
- package/scss/config/_density.scss +117 -0
- package/scss/config/_icons.scss +37 -0
- package/scss/config/_mixins.scss +13 -0
- package/scss/config/_theme.scss +216 -0
- package/scss/config/_tokens.scss +419 -0
- package/scss/config/mixins/_accordion.scss +52 -0
- package/scss/config/mixins/_ajax.scss +39 -0
- package/scss/config/mixins/_alert.scss +82 -0
- package/scss/config/mixins/_app-shell.scss +312 -0
- package/scss/config/mixins/_avatar.scss +109 -0
- package/scss/config/mixins/_borders.scss +36 -0
- package/scss/config/mixins/_breadcrumbs.scss +72 -0
- package/scss/config/mixins/_breakpoints.scss +62 -0
- package/scss/config/mixins/_btn.scss +179 -0
- package/scss/config/mixins/_card.scss +338 -0
- package/scss/config/mixins/_chip.scss +66 -0
- package/scss/config/mixins/_circular-progress.scss +71 -0
- package/scss/config/mixins/_collapsible.scss +24 -0
- package/scss/config/mixins/_colors.scss +46 -0
- package/scss/config/mixins/_confirm.scss +31 -0
- package/scss/config/mixins/_data-table.scss +346 -0
- package/scss/config/mixins/_display.scss +32 -0
- package/scss/config/mixins/_dropdown.scss +143 -0
- package/scss/config/mixins/_empty-state.scss +30 -0
- package/scss/config/mixins/_focus.scss +55 -0
- package/scss/config/mixins/_footer.scss +42 -0
- package/scss/config/mixins/_form.scss +601 -0
- package/scss/config/mixins/_index.scss +58 -0
- package/scss/config/mixins/_interaction.scss +15 -0
- package/scss/config/mixins/_kbd.scss +22 -0
- package/scss/config/mixins/_layout.scss +117 -0
- package/scss/config/mixins/_link.scss +55 -0
- package/scss/config/mixins/_ln-table.scss +420 -0
- package/scss/config/mixins/_loader.scss +26 -0
- package/scss/config/mixins/_modal.scss +66 -0
- package/scss/config/mixins/_motion.scss +19 -0
- package/scss/config/mixins/_nav.scss +273 -0
- package/scss/config/mixins/_page-header.scss +69 -0
- package/scss/config/mixins/_popover.scss +25 -0
- package/scss/config/mixins/_position.scss +32 -0
- package/scss/config/mixins/_progress.scss +56 -0
- package/scss/config/mixins/_prose.scss +127 -0
- package/scss/config/mixins/_shadows.scss +8 -0
- package/scss/config/mixins/_sidebar.scss +95 -0
- package/scss/config/mixins/_sizing.scss +6 -0
- package/scss/config/mixins/_spacing.scss +19 -0
- package/scss/config/mixins/_stat-card.scss +68 -0
- package/scss/config/mixins/_status-badge.scss +83 -0
- package/scss/config/mixins/_stepper.scss +78 -0
- package/scss/config/mixins/_table.scss +215 -0
- package/scss/config/mixins/_tabs.scss +64 -0
- package/scss/config/mixins/_timeline.scss +69 -0
- package/scss/config/mixins/_toast.scss +148 -0
- package/scss/config/mixins/_tooltip.scss +111 -0
- package/scss/config/mixins/_transitions.scss +10 -0
- package/scss/config/mixins/_translations.scss +124 -0
- package/scss/config/mixins/_typography.scss +57 -0
- package/scss/config/mixins/_upload.scss +168 -0
- package/scss/ln-ashlar.scss +62 -0
- package/scss/tabler-icons.txt +5039 -0
- package/scss/utilities/_animations.scss +83 -0
- package/scss/utilities/_utilities.scss +49 -0
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
@use 'spacing' as *;
|
|
2
|
+
@use 'display' as *;
|
|
3
|
+
@use 'breakpoints' as *;
|
|
4
|
+
|
|
5
|
+
// Layout — grid, stack, container
|
|
6
|
+
|
|
7
|
+
@mixin grid {
|
|
8
|
+
display: grid;
|
|
9
|
+
--gap: var(--size-lg);
|
|
10
|
+
gap: var(--gap);
|
|
11
|
+
grid-template-columns: repeat(1, minmax(0, 1fr));
|
|
12
|
+
|
|
13
|
+
@include mq-up(md) {
|
|
14
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
@include mq-up(lg) {
|
|
18
|
+
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
@mixin grid-2 {
|
|
23
|
+
display: grid;
|
|
24
|
+
--gap: var(--size-lg);
|
|
25
|
+
gap: var(--gap);
|
|
26
|
+
grid-template-columns: repeat(1, minmax(0, 1fr));
|
|
27
|
+
|
|
28
|
+
@include mq-up(md) {
|
|
29
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
@mixin grid-4 {
|
|
34
|
+
display: grid;
|
|
35
|
+
--gap: var(--size-lg);
|
|
36
|
+
gap: var(--gap);
|
|
37
|
+
grid-template-columns: repeat(1, minmax(0, 1fr));
|
|
38
|
+
|
|
39
|
+
@include mq-up(md) {
|
|
40
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
@include mq-up(lg) {
|
|
44
|
+
grid-template-columns: repeat(4, minmax(0, 1fr));
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
@mixin stack($gap: var(--gap)) {
|
|
49
|
+
@include flex-col;
|
|
50
|
+
@include gap($gap);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
@mixin row($gap: var(--gap)) {
|
|
54
|
+
@include flex-row;
|
|
55
|
+
@include items-center;
|
|
56
|
+
@include gap($gap);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
@mixin row-between($gap: var(--gap)) {
|
|
60
|
+
@include row($gap);
|
|
61
|
+
@include justify-between;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
@mixin row-center($gap: var(--gap)) {
|
|
65
|
+
@include row($gap);
|
|
66
|
+
@include justify-center;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Container Queries
|
|
70
|
+
// Parent: @include container(name)
|
|
71
|
+
// Child: @include cq-up(compact, name) { ... }
|
|
72
|
+
//
|
|
73
|
+
// IMPORTANT: Do NOT combine container-type with overflow:hidden on the same element
|
|
74
|
+
//
|
|
75
|
+
// Breakpoints: 480px, 580px, 880px, 1120px
|
|
76
|
+
@mixin container($name: null) {
|
|
77
|
+
// Nameless form is intentional — models native anonymous @container queries.
|
|
78
|
+
// See docs/css/layout.md ("Anonymous container") and demo/admin/mixins.html.
|
|
79
|
+
container-type: inline-size;
|
|
80
|
+
@if $name { container-name: $name; }
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// ─── Flat stack ────────────────────────────────────────
|
|
84
|
+
// Vertical joined-panel pattern: children sit flush with a single
|
|
85
|
+
// shared horizontal rule between them. Consumes the per-side border
|
|
86
|
+
// soft token `--border-block-start` (no :root default) to suppress
|
|
87
|
+
// each child's top edge after the first.
|
|
88
|
+
//
|
|
89
|
+
// Works on any child that reads --radius and --shadow for
|
|
90
|
+
// its own chrome (card, section-card, stat-card, bare <article>
|
|
91
|
+
// with @include card). Self-contained: also re-binds --radius: 0
|
|
92
|
+
// and --shadow: none on direct children so rounded corners
|
|
93
|
+
// and elevation shadows do not conflict with the flat shared rule.
|
|
94
|
+
//
|
|
95
|
+
// Cascade note: the --radius / --shadow re-binds cascade
|
|
96
|
+
// into grandchildren. If a consumer nests a rounded card inside a
|
|
97
|
+
// flat-stack panel, re-bind --radius on that nested element.
|
|
98
|
+
//
|
|
99
|
+
// Block-axis only. For horizontal joined controls use btn-group or
|
|
100
|
+
// pill-group — they use border-radius tricks on first/last children
|
|
101
|
+
// instead of border-block-* suppression.
|
|
102
|
+
//
|
|
103
|
+
// Usage:
|
|
104
|
+
// .flat-stack { @include flat-stack; } // prototype class
|
|
105
|
+
// #users > ul { @include flat-stack; } // project selector
|
|
106
|
+
@mixin flat-stack {
|
|
107
|
+
--gap: 0;
|
|
108
|
+
|
|
109
|
+
> * {
|
|
110
|
+
--radius: 0;
|
|
111
|
+
--shadow: none;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
> * + * {
|
|
115
|
+
--border-block-start: none;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
@use 'display' as *;
|
|
2
|
+
@use 'spacing' as *;
|
|
3
|
+
@use 'typography' as *;
|
|
4
|
+
@use 'colors' as *;
|
|
5
|
+
@use 'borders' as *;
|
|
6
|
+
@use 'position' as *;
|
|
7
|
+
@use 'interaction' as *;
|
|
8
|
+
@use 'motion' as *;
|
|
9
|
+
|
|
10
|
+
// Clickable rows — cursor + selection prevention for data-ln-link containers.
|
|
11
|
+
//
|
|
12
|
+
// Usage:
|
|
13
|
+
// [data-ln-link] tr { @include link-row; }
|
|
14
|
+
|
|
15
|
+
@mixin link-row {
|
|
16
|
+
@include cursor-pointer;
|
|
17
|
+
@include select-none;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Status bar — mimics browser's native URL preview at bottom-left.
|
|
21
|
+
//
|
|
22
|
+
// Usage:
|
|
23
|
+
// .ln-link-status { @include link-status; }
|
|
24
|
+
//
|
|
25
|
+
// JS toggles .ln-link-status--visible to show/hide.
|
|
26
|
+
|
|
27
|
+
@mixin link-status {
|
|
28
|
+
@include fixed;
|
|
29
|
+
bottom: 0;
|
|
30
|
+
left: 0;
|
|
31
|
+
--padding-y: var(--size-xs);
|
|
32
|
+
--padding-x: var(--size-sm-up);
|
|
33
|
+
padding: var(--padding-y) var(--padding-x);
|
|
34
|
+
background: var(--color-bg);
|
|
35
|
+
@include border-t;
|
|
36
|
+
@include border-r;
|
|
37
|
+
@include text-xs;
|
|
38
|
+
--color-fg: var(--fg-muted);
|
|
39
|
+
color: var(--color-fg);
|
|
40
|
+
@include rounded-sm;
|
|
41
|
+
border-bottom-left-radius: 0;
|
|
42
|
+
border-top-left-radius: 0;
|
|
43
|
+
max-width: 50vw;
|
|
44
|
+
@include truncate;
|
|
45
|
+
@include z-toast;
|
|
46
|
+
opacity: 0;
|
|
47
|
+
pointer-events: none;
|
|
48
|
+
@include motion-safe {
|
|
49
|
+
transition: opacity var(--transition-fast);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
&--visible {
|
|
53
|
+
opacity: 1;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
@use 'display' as *;
|
|
2
|
+
@use 'spacing' as *;
|
|
3
|
+
@use 'sizing' as *;
|
|
4
|
+
@use 'typography' as *;
|
|
5
|
+
@use 'colors' as *;
|
|
6
|
+
@use 'borders' as *;
|
|
7
|
+
@use 'shadows' as *;
|
|
8
|
+
@use 'position' as *;
|
|
9
|
+
@use 'transitions' as *;
|
|
10
|
+
@use 'interaction' as *;
|
|
11
|
+
@use 'motion' as *;
|
|
12
|
+
@use 'layout' as *;
|
|
13
|
+
@use 'card' as *;
|
|
14
|
+
|
|
15
|
+
// ln-table -- Enhanced data table wrapper component.
|
|
16
|
+
//
|
|
17
|
+
// Provides toolbar, sticky headers, column filter dropdowns, sort
|
|
18
|
+
// indicators, footer, filter chips, empty state, timing badge.
|
|
19
|
+
//
|
|
20
|
+
// Usage:
|
|
21
|
+
// [data-ln-table] { @include ln-table; }
|
|
22
|
+
// .ln-table__toolbar { @include ln-table-toolbar; }
|
|
23
|
+
//
|
|
24
|
+
// State-driven CSS (spacer rows, sort icon .hidden toggle, content overflow
|
|
25
|
+
// fix) stays in the co-located JS SCSS file.
|
|
26
|
+
|
|
27
|
+
@mixin ln-table {
|
|
28
|
+
@include border;
|
|
29
|
+
--radius: var(--radius-lg);
|
|
30
|
+
border-radius: var(--radius);
|
|
31
|
+
background: var(--color-bg);
|
|
32
|
+
overflow: clip;
|
|
33
|
+
|
|
34
|
+
// Table overrides inside component
|
|
35
|
+
table {
|
|
36
|
+
overflow: visible;
|
|
37
|
+
border-collapse: separate;
|
|
38
|
+
border-spacing: 0;
|
|
39
|
+
border-radius: 0;
|
|
40
|
+
box-shadow: none;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Whole thead sticky as one unit (toolbar row + column-headers row).
|
|
44
|
+
// Wrapper's `overflow: clip` + `rounded-lg` clip the top corners,
|
|
45
|
+
// so per-th radius is unnecessary.
|
|
46
|
+
thead {
|
|
47
|
+
@include sticky-top;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
thead th {
|
|
51
|
+
background: var(--bg-sunken);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// First td override -- remove global bold/bg
|
|
55
|
+
table td:first-child {
|
|
56
|
+
background: transparent;
|
|
57
|
+
font-weight: normal;
|
|
58
|
+
--color-fg: var(--fg-muted);
|
|
59
|
+
color: var(--color-fg);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// ─── Toolbar ──────────────────────────────────────────────
|
|
64
|
+
|
|
65
|
+
@mixin ln-table-toolbar {
|
|
66
|
+
@include panel-header;
|
|
67
|
+
position: sticky;
|
|
68
|
+
top: 0;
|
|
69
|
+
z-index: var(--z-sticky);
|
|
70
|
+
border-radius: var(--radius-lg) var(--radius-lg) 0 0;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// ─── In-thead toolbar (first thead row, single colspan th) ───────
|
|
74
|
+
//
|
|
75
|
+
// Applied to the <th colspan="N"> in the first thead row of an
|
|
76
|
+
// ln-table. Expected HTML:
|
|
77
|
+
//
|
|
78
|
+
// <tr><th colspan="N"><div> ...toolbar content... </div></th></tr>
|
|
79
|
+
//
|
|
80
|
+
// The <th> stays display:table-cell so colspan participates in
|
|
81
|
+
// table layout normally. The wrapper <div> carries the panel-header
|
|
82
|
+
// chrome (flex layout, padding, border-bottom, sunken bg). The
|
|
83
|
+
// <th> itself gets padding:0 plus explicit resets to break the
|
|
84
|
+
// @mixin table-base cascade (uppercase / text-label-sm /
|
|
85
|
+
// letter-spacing / semibold) so the toolbar's <h3>, <span>, <label>
|
|
86
|
+
// children render with normal text styling, not column-header
|
|
87
|
+
// styling.
|
|
88
|
+
|
|
89
|
+
@mixin ln-table-thead-toolbar {
|
|
90
|
+
// <th> resets — chrome lives on the inner <div>.
|
|
91
|
+
padding: 0;
|
|
92
|
+
text-align: left;
|
|
93
|
+
text-transform: none;
|
|
94
|
+
letter-spacing: normal;
|
|
95
|
+
font-size: var(--font-size);
|
|
96
|
+
font-weight: normal;
|
|
97
|
+
|
|
98
|
+
> div {
|
|
99
|
+
@include panel-header;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
@mixin ln-table-toolbar-search {
|
|
104
|
+
width: 10rem;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// ─── Count badge ──────────────────────────────────────────
|
|
108
|
+
|
|
109
|
+
@mixin ln-table-count {
|
|
110
|
+
@include text-sm;
|
|
111
|
+
--color-fg: var(--fg-muted);
|
|
112
|
+
color: var(--color-fg);
|
|
113
|
+
|
|
114
|
+
strong {
|
|
115
|
+
color: var(--color-fg);
|
|
116
|
+
@include font-semibold;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// ─── Card mode container query ────────────────────────────
|
|
121
|
+
|
|
122
|
+
@mixin ln-table-card-mode {
|
|
123
|
+
@container table (max-width: 640px) {
|
|
124
|
+
colgroup { display: none; }
|
|
125
|
+
table { table-layout: auto !important; }
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// ─── Column filter dropdowns in th ────────────────────────
|
|
130
|
+
|
|
131
|
+
@mixin ln-table-column-filter {
|
|
132
|
+
th [data-ln-dropdown] {
|
|
133
|
+
@include inline-flex;
|
|
134
|
+
@include items-center;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
th [data-ln-dropdown] > button {
|
|
138
|
+
@include flex;
|
|
139
|
+
@include items-center;
|
|
140
|
+
--gap: var(--size-xs);
|
|
141
|
+
gap: var(--gap);
|
|
142
|
+
background: none;
|
|
143
|
+
border: none;
|
|
144
|
+
color: inherit;
|
|
145
|
+
font: inherit;
|
|
146
|
+
@include cursor-pointer;
|
|
147
|
+
--btn-padding-y: 0;
|
|
148
|
+
--btn-padding-x: 0;
|
|
149
|
+
|
|
150
|
+
.ln-icon-filter {
|
|
151
|
+
opacity: 0.4;
|
|
152
|
+
@include motion-safe {
|
|
153
|
+
transition: opacity var(--transition-fast);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
&:hover .ln-icon-filter {
|
|
158
|
+
opacity: 1;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
th [data-ln-dropdown-menu] button[data-ln-filter-key] {
|
|
163
|
+
@include w-full;
|
|
164
|
+
@include flex;
|
|
165
|
+
@include items-center;
|
|
166
|
+
@include text-left;
|
|
167
|
+
--btn-padding-y: var(--size-xs);
|
|
168
|
+
--btn-padding-x: var(--size-sm);
|
|
169
|
+
@include text-sm;
|
|
170
|
+
@include font-normal;
|
|
171
|
+
background: none;
|
|
172
|
+
border: none;
|
|
173
|
+
border-radius: 0;
|
|
174
|
+
color: var(--color-fg);
|
|
175
|
+
@include cursor-pointer;
|
|
176
|
+
@include transition-fast;
|
|
177
|
+
|
|
178
|
+
&:hover {
|
|
179
|
+
--color-bg: var(--bg-sunken);
|
|
180
|
+
background: var(--color-bg);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
&[data-active] {
|
|
184
|
+
background-color: color-mix(in srgb, var(--color-accent) 10%, transparent);
|
|
185
|
+
color: var(--color-accent);
|
|
186
|
+
@include font-medium;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// ─── Sort indicators on th ────────────────────────────────
|
|
192
|
+
|
|
193
|
+
@mixin ln-table-sort {
|
|
194
|
+
th[data-ln-sort] {
|
|
195
|
+
@include cursor-pointer;
|
|
196
|
+
@include select-none;
|
|
197
|
+
|
|
198
|
+
[data-ln-sort-icon] {
|
|
199
|
+
@include size(0.875rem);
|
|
200
|
+
--margin-inline: var(--size-xs);
|
|
201
|
+
margin-left: var(--margin-inline);
|
|
202
|
+
vertical-align: middle;
|
|
203
|
+
opacity: 0.4;
|
|
204
|
+
@include motion-safe {
|
|
205
|
+
transition: opacity var(--transition-fast);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
&:hover [data-ln-sort-icon] {
|
|
210
|
+
opacity: 0.7;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
&[data-ln-sort-active] [data-ln-sort-icon] {
|
|
214
|
+
opacity: 1;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// ─── Footer ───────────────────────────────────────────────
|
|
220
|
+
|
|
221
|
+
@mixin ln-table-footer {
|
|
222
|
+
@include flex;
|
|
223
|
+
@include items-center;
|
|
224
|
+
@include justify-between;
|
|
225
|
+
--padding-y: var(--size-sm);
|
|
226
|
+
--padding-x: var(--size-md);
|
|
227
|
+
padding: var(--padding-y) var(--padding-x);
|
|
228
|
+
@include border-t;
|
|
229
|
+
--color-bg: var(--bg-sunken);
|
|
230
|
+
background: var(--color-bg);
|
|
231
|
+
border-radius: 0 0 var(--radius-lg) var(--radius-lg);
|
|
232
|
+
@include text-sm;
|
|
233
|
+
--color-fg: var(--fg-muted);
|
|
234
|
+
color: var(--color-fg);
|
|
235
|
+
|
|
236
|
+
strong {
|
|
237
|
+
color: var(--color-fg);
|
|
238
|
+
@include font-semibold;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// ─── Timing badge ─────────────────────────────────────────
|
|
243
|
+
|
|
244
|
+
@mixin ln-table-timing {
|
|
245
|
+
@include text-xs;
|
|
246
|
+
--color-fg: var(--fg-subtle);
|
|
247
|
+
color: var(--color-fg);
|
|
248
|
+
font-family: var(--font-mono);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// ─── Quick filter bar ─────────────────────────────────────
|
|
252
|
+
|
|
253
|
+
@mixin ln-table-filters {
|
|
254
|
+
@include flex;
|
|
255
|
+
@include flex-wrap;
|
|
256
|
+
@include items-center;
|
|
257
|
+
--gap: var(--size-lg);
|
|
258
|
+
gap: var(--gap);
|
|
259
|
+
--padding-y: var(--size-sm);
|
|
260
|
+
--padding-x: var(--size-md);
|
|
261
|
+
padding: var(--padding-y) var(--padding-x);
|
|
262
|
+
@include border-b;
|
|
263
|
+
|
|
264
|
+
fieldset {
|
|
265
|
+
border: none;
|
|
266
|
+
padding: 0;
|
|
267
|
+
margin: 0;
|
|
268
|
+
@include flex;
|
|
269
|
+
@include items-center;
|
|
270
|
+
--gap: var(--size-xs-up);
|
|
271
|
+
gap: var(--gap);
|
|
272
|
+
|
|
273
|
+
legend {
|
|
274
|
+
@include text-xs;
|
|
275
|
+
@include font-medium;
|
|
276
|
+
--color-fg: var(--fg-subtle);
|
|
277
|
+
color: var(--color-fg);
|
|
278
|
+
float: left;
|
|
279
|
+
--margin-inline: var(--size-sm);
|
|
280
|
+
margin-right: var(--margin-inline);
|
|
281
|
+
line-height: 1.75rem;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
ul {
|
|
285
|
+
@include inline-flex;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
li button {
|
|
289
|
+
--btn-padding-y: var(--size-2xs);
|
|
290
|
+
--btn-padding-x: var(--size-sm);
|
|
291
|
+
@include text-xs;
|
|
292
|
+
@include font-medium;
|
|
293
|
+
@include rounded-full;
|
|
294
|
+
@include transition-fast;
|
|
295
|
+
background: transparent;
|
|
296
|
+
--color-fg: var(--fg-muted);
|
|
297
|
+
color: var(--color-fg);
|
|
298
|
+
border: none;
|
|
299
|
+
|
|
300
|
+
&:hover {
|
|
301
|
+
--color-bg: var(--bg-sunken);
|
|
302
|
+
background-color: var(--color-bg);
|
|
303
|
+
color: var(--color-fg);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
&[data-active] {
|
|
307
|
+
background-color: color-mix(in srgb, var(--color-accent) 10%, transparent);
|
|
308
|
+
color: var(--color-accent);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// ─── Active filter chips ──────────────────────────────────
|
|
315
|
+
|
|
316
|
+
@mixin ln-table-chips {
|
|
317
|
+
@include flex;
|
|
318
|
+
@include items-center;
|
|
319
|
+
@include flex-wrap;
|
|
320
|
+
--gap: var(--size-xs-up);
|
|
321
|
+
gap: var(--gap);
|
|
322
|
+
--padding-y: var(--size-xs-up);
|
|
323
|
+
--padding-x: var(--size-md);
|
|
324
|
+
padding: var(--padding-y) var(--padding-x);
|
|
325
|
+
@include border-b;
|
|
326
|
+
background-color: color-mix(in srgb, var(--color-accent) 3%, transparent);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
@mixin ln-table-chip {
|
|
330
|
+
@include inline-flex;
|
|
331
|
+
@include items-center;
|
|
332
|
+
--gap: var(--size-xs);
|
|
333
|
+
gap: var(--gap);
|
|
334
|
+
--padding-y: var(--size-2xs);
|
|
335
|
+
--padding-x: var(--size-sm);
|
|
336
|
+
padding: var(--padding-y) var(--padding-x);
|
|
337
|
+
@include rounded-full;
|
|
338
|
+
@include text-xs;
|
|
339
|
+
@include tinted-surface(0.1);
|
|
340
|
+
|
|
341
|
+
strong {
|
|
342
|
+
@include font-semibold;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
button {
|
|
346
|
+
background: none;
|
|
347
|
+
border: none;
|
|
348
|
+
color: var(--color-accent);
|
|
349
|
+
@include cursor-pointer;
|
|
350
|
+
@include text-sm;
|
|
351
|
+
@include font-bold;
|
|
352
|
+
line-height: 1;
|
|
353
|
+
--btn-padding-y: 0;
|
|
354
|
+
--btn-padding-x: 0;
|
|
355
|
+
--margin-inline: var(--size-2xs);
|
|
356
|
+
margin-left: var(--margin-inline);
|
|
357
|
+
|
|
358
|
+
&:hover {
|
|
359
|
+
color: hsl(var(--color-error));
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
@mixin ln-table-clear-all {
|
|
365
|
+
@include text-xs;
|
|
366
|
+
@include font-medium;
|
|
367
|
+
--color-fg: var(--fg-subtle);
|
|
368
|
+
color: var(--color-fg);
|
|
369
|
+
background: none;
|
|
370
|
+
border: none;
|
|
371
|
+
@include cursor-pointer;
|
|
372
|
+
--margin-inline: var(--size-xs);
|
|
373
|
+
margin-left: var(--margin-inline);
|
|
374
|
+
|
|
375
|
+
&:hover {
|
|
376
|
+
color: hsl(var(--color-error));
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// ─── Empty state ──────────────────────────────────────────
|
|
381
|
+
|
|
382
|
+
@mixin ln-table-empty-state {
|
|
383
|
+
--padding-y: var(--size-2xl);
|
|
384
|
+
padding-block: var(--padding-y);
|
|
385
|
+
@include text-center;
|
|
386
|
+
|
|
387
|
+
svg.ln-icon {
|
|
388
|
+
@include block;
|
|
389
|
+
@include mx(auto);
|
|
390
|
+
--margin-block: var(--size-md);
|
|
391
|
+
margin-bottom: var(--margin-block);
|
|
392
|
+
opacity: 0.3;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
h3 {
|
|
396
|
+
@include text-lg;
|
|
397
|
+
@include font-semibold;
|
|
398
|
+
color: var(--color-fg);
|
|
399
|
+
--margin-block: var(--size-sm);
|
|
400
|
+
margin: 0 0 var(--margin-block);
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
p {
|
|
404
|
+
@include text-sm;
|
|
405
|
+
--color-fg: var(--fg-muted);
|
|
406
|
+
color: var(--color-fg);
|
|
407
|
+
--margin-block: var(--size-lg);
|
|
408
|
+
margin: 0 0 var(--margin-block);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
// Virtual-scroll spacer rows (JS-injected) — neutralize cell chrome including bg.
|
|
413
|
+
|
|
414
|
+
@mixin ln-table-spacer-row {
|
|
415
|
+
td {
|
|
416
|
+
padding: 0 !important;
|
|
417
|
+
border: none !important;
|
|
418
|
+
background: transparent !important;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
@use 'display' as *;
|
|
2
|
+
@use 'spacing' as *;
|
|
3
|
+
@use 'sizing' as *;
|
|
4
|
+
@use 'position' as *;
|
|
5
|
+
@use 'colors' as *;
|
|
6
|
+
@use 'motion' as *;
|
|
7
|
+
|
|
8
|
+
@mixin loader {
|
|
9
|
+
color: var(--color-accent);
|
|
10
|
+
// Spinner is drawn with em-based box-shadow; font-size is the intrinsic
|
|
11
|
+
// size knob. Callers override per-use (e.g. font-size: 32px) — see
|
|
12
|
+
// docs/css/loader.md. Page-level margin is a binding concern, not a
|
|
13
|
+
// mixin concern, and lives on the consumer selector.
|
|
14
|
+
font-size: 90px;
|
|
15
|
+
text-indent: -9999em;
|
|
16
|
+
@include overflow-hidden;
|
|
17
|
+
width: 1em;
|
|
18
|
+
height: 1em;
|
|
19
|
+
border-radius: 50%;
|
|
20
|
+
@include mx(auto);
|
|
21
|
+
@include relative;
|
|
22
|
+
transform: translateZ(0);
|
|
23
|
+
@include motion-safe {
|
|
24
|
+
animation: loader-spin 1.7s infinite ease, loader-round 1.7s infinite ease;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
@use 'display' as *;
|
|
2
|
+
@use 'spacing' as *;
|
|
3
|
+
@use 'position' as *;
|
|
4
|
+
@use 'motion' as *;
|
|
5
|
+
@use 'card' as *;
|
|
6
|
+
|
|
7
|
+
// Modal size mixins
|
|
8
|
+
// Usage: #my-modal > form { @include modal-lg; }
|
|
9
|
+
|
|
10
|
+
@mixin modal-sm { max-width: 28rem; }
|
|
11
|
+
@mixin modal-md { max-width: 32rem; }
|
|
12
|
+
@mixin modal-lg { max-width: 42rem; }
|
|
13
|
+
@mixin modal-xl { max-width: 48rem; }
|
|
14
|
+
|
|
15
|
+
// ─── Modal layout ──────────────────────────────────────
|
|
16
|
+
|
|
17
|
+
// Overlay backdrop — covers viewport, darkened + blurred.
|
|
18
|
+
// Default: hidden (display:none). JS sets [data-ln-modal="open"]
|
|
19
|
+
// to show — that state rule lives in the co-located JS SCSS.
|
|
20
|
+
@mixin modal-overlay {
|
|
21
|
+
display: none;
|
|
22
|
+
@include fixed;
|
|
23
|
+
@include inset-0;
|
|
24
|
+
background-color: var(--color-scrim);
|
|
25
|
+
backdrop-filter: blur(4px);
|
|
26
|
+
-webkit-backdrop-filter: blur(4px);
|
|
27
|
+
z-index: var(--z-modal);
|
|
28
|
+
@include items-center;
|
|
29
|
+
@include justify-center;
|
|
30
|
+
opacity: 0;
|
|
31
|
+
@include motion-safe {
|
|
32
|
+
transition: opacity var(--transition);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Content panel — the <form> inside .ln-modal.
|
|
37
|
+
// Structurally IS a section-card: reuse its chrome and its nested
|
|
38
|
+
// > header / > main / > footer recipes. Add only the modal-specific
|
|
39
|
+
// behaviour on top: fixed size envelope, scrollable body, sticky
|
|
40
|
+
// footer, slide-in animation, deeper shadow.
|
|
41
|
+
@mixin modal-panel {
|
|
42
|
+
@include section-card;
|
|
43
|
+
margin-bottom: 0;
|
|
44
|
+
// Explicit role-scale read — modals use max elevation (deeper than
|
|
45
|
+
// the --shadow-floating default used by floating panels).
|
|
46
|
+
box-shadow: var(--shadow-xl);
|
|
47
|
+
display: grid;
|
|
48
|
+
grid-template-rows: auto 1fr auto;
|
|
49
|
+
max-width: 600px;
|
|
50
|
+
width: 90%;
|
|
51
|
+
max-height: 90vh;
|
|
52
|
+
@include motion-safe {
|
|
53
|
+
animation: ln-modal-slideIn var(--transition-slow);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
> main {
|
|
57
|
+
min-height: 0;
|
|
58
|
+
overflow-y: auto;
|
|
59
|
+
overflow-x: hidden;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
> footer {
|
|
63
|
+
position: sticky;
|
|
64
|
+
bottom: 0;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// Motion safety — gate animation-only declarations behind
|
|
2
|
+
// prefers-reduced-motion: no-preference.
|
|
3
|
+
//
|
|
4
|
+
// Usage:
|
|
5
|
+
// .ln-modal__overlay {
|
|
6
|
+
// @include motion-safe {
|
|
7
|
+
// animation: fadeIn var(--transition-base);
|
|
8
|
+
// }
|
|
9
|
+
// }
|
|
10
|
+
//
|
|
11
|
+
// Color transitions on hover are fine unwrapped — they do not trigger
|
|
12
|
+
// vestibular issues. Only wrap transform, opacity, translate, scale,
|
|
13
|
+
// rotate, and keyframe animations.
|
|
14
|
+
|
|
15
|
+
@mixin motion-safe {
|
|
16
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
17
|
+
@content;
|
|
18
|
+
}
|
|
19
|
+
}
|