nativecorejs 0.1.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/README.md +22 -0
- package/dist/components/builtinRegistry.d.ts +2 -0
- package/dist/components/builtinRegistry.js +72 -0
- package/dist/components/index.d.ts +59 -0
- package/dist/components/index.js +59 -0
- package/dist/components/loading-spinner.d.ts +5 -0
- package/dist/components/loading-spinner.js +48 -0
- package/dist/components/nc-a.d.ts +45 -0
- package/dist/components/nc-a.js +290 -0
- package/dist/components/nc-accordion.d.ts +36 -0
- package/dist/components/nc-accordion.js +186 -0
- package/dist/components/nc-alert.d.ts +11 -0
- package/dist/components/nc-alert.js +127 -0
- package/dist/components/nc-animation.d.ts +117 -0
- package/dist/components/nc-animation.js +1053 -0
- package/dist/components/nc-autocomplete.d.ts +41 -0
- package/dist/components/nc-autocomplete.js +275 -0
- package/dist/components/nc-avatar-group.d.ts +7 -0
- package/dist/components/nc-avatar-group.js +85 -0
- package/dist/components/nc-avatar.d.ts +9 -0
- package/dist/components/nc-avatar.js +127 -0
- package/dist/components/nc-badge.d.ts +7 -0
- package/dist/components/nc-badge.js +63 -0
- package/dist/components/nc-bottom-nav.d.ts +53 -0
- package/dist/components/nc-bottom-nav.js +198 -0
- package/dist/components/nc-breadcrumb.d.ts +10 -0
- package/dist/components/nc-breadcrumb.js +71 -0
- package/dist/components/nc-button.d.ts +38 -0
- package/dist/components/nc-button.js +293 -0
- package/dist/components/nc-card.d.ts +11 -0
- package/dist/components/nc-card.js +74 -0
- package/dist/components/nc-checkbox.d.ts +16 -0
- package/dist/components/nc-checkbox.js +194 -0
- package/dist/components/nc-chip.d.ts +8 -0
- package/dist/components/nc-chip.js +89 -0
- package/dist/components/nc-code.d.ts +37 -0
- package/dist/components/nc-code.js +315 -0
- package/dist/components/nc-collapsible.d.ts +33 -0
- package/dist/components/nc-collapsible.js +148 -0
- package/dist/components/nc-color-picker.d.ts +33 -0
- package/dist/components/nc-color-picker.js +265 -0
- package/dist/components/nc-copy-button.d.ts +10 -0
- package/dist/components/nc-copy-button.js +94 -0
- package/dist/components/nc-date-picker.d.ts +41 -0
- package/dist/components/nc-date-picker.js +443 -0
- package/dist/components/nc-div.d.ts +53 -0
- package/dist/components/nc-div.js +270 -0
- package/dist/components/nc-divider.d.ts +7 -0
- package/dist/components/nc-divider.js +57 -0
- package/dist/components/nc-drawer.d.ts +40 -0
- package/dist/components/nc-drawer.js +217 -0
- package/dist/components/nc-dropdown.d.ts +41 -0
- package/dist/components/nc-dropdown.js +170 -0
- package/dist/components/nc-empty-state.d.ts +5 -0
- package/dist/components/nc-empty-state.js +76 -0
- package/dist/components/nc-file-upload.d.ts +40 -0
- package/dist/components/nc-file-upload.js +336 -0
- package/dist/components/nc-form.d.ts +70 -0
- package/dist/components/nc-form.js +273 -0
- package/dist/components/nc-image.d.ts +10 -0
- package/dist/components/nc-image.js +139 -0
- package/dist/components/nc-input.d.ts +25 -0
- package/dist/components/nc-input.js +302 -0
- package/dist/components/nc-kbd.d.ts +5 -0
- package/dist/components/nc-kbd.js +34 -0
- package/dist/components/nc-menu-item.d.ts +43 -0
- package/dist/components/nc-menu-item.js +182 -0
- package/dist/components/nc-menu.d.ts +76 -0
- package/dist/components/nc-menu.js +360 -0
- package/dist/components/nc-modal.d.ts +51 -0
- package/dist/components/nc-modal.js +231 -0
- package/dist/components/nc-nav-item.d.ts +35 -0
- package/dist/components/nc-nav-item.js +142 -0
- package/dist/components/nc-number-input.d.ts +22 -0
- package/dist/components/nc-number-input.js +270 -0
- package/dist/components/nc-otp-input.d.ts +41 -0
- package/dist/components/nc-otp-input.js +227 -0
- package/dist/components/nc-pagination.d.ts +28 -0
- package/dist/components/nc-pagination.js +171 -0
- package/dist/components/nc-popover.d.ts +58 -0
- package/dist/components/nc-popover.js +301 -0
- package/dist/components/nc-progress-circular.d.ts +7 -0
- package/dist/components/nc-progress-circular.js +67 -0
- package/dist/components/nc-progress.d.ts +7 -0
- package/dist/components/nc-progress.js +109 -0
- package/dist/components/nc-radio.d.ts +13 -0
- package/dist/components/nc-radio.js +169 -0
- package/dist/components/nc-rating.d.ts +19 -0
- package/dist/components/nc-rating.js +187 -0
- package/dist/components/nc-rich-text.d.ts +43 -0
- package/dist/components/nc-rich-text.js +310 -0
- package/dist/components/nc-scroll-top.d.ts +28 -0
- package/dist/components/nc-scroll-top.js +103 -0
- package/dist/components/nc-select.d.ts +51 -0
- package/dist/components/nc-select.js +425 -0
- package/dist/components/nc-skeleton.d.ts +7 -0
- package/dist/components/nc-skeleton.js +90 -0
- package/dist/components/nc-slider.d.ts +41 -0
- package/dist/components/nc-slider.js +268 -0
- package/dist/components/nc-snackbar.d.ts +51 -0
- package/dist/components/nc-snackbar.js +200 -0
- package/dist/components/nc-splash.d.ts +25 -0
- package/dist/components/nc-splash.js +296 -0
- package/dist/components/nc-stepper.d.ts +50 -0
- package/dist/components/nc-stepper.js +236 -0
- package/dist/components/nc-switch.d.ts +14 -0
- package/dist/components/nc-switch.js +194 -0
- package/dist/components/nc-tab-item.d.ts +39 -0
- package/dist/components/nc-tab-item.js +127 -0
- package/dist/components/nc-table.d.ts +44 -0
- package/dist/components/nc-table.js +265 -0
- package/dist/components/nc-tabs.d.ts +79 -0
- package/dist/components/nc-tabs.js +519 -0
- package/dist/components/nc-tag-input.d.ts +49 -0
- package/dist/components/nc-tag-input.js +268 -0
- package/dist/components/nc-textarea.d.ts +15 -0
- package/dist/components/nc-textarea.js +164 -0
- package/dist/components/nc-time-picker.d.ts +51 -0
- package/dist/components/nc-time-picker.js +452 -0
- package/dist/components/nc-timeline.d.ts +53 -0
- package/dist/components/nc-timeline.js +171 -0
- package/dist/components/nc-tooltip.d.ts +27 -0
- package/dist/components/nc-tooltip.js +135 -0
- package/dist/core/component.d.ts +33 -0
- package/dist/core/component.js +208 -0
- package/dist/core/gpu-animation.d.ts +141 -0
- package/dist/core/gpu-animation.js +474 -0
- package/dist/core/lazyComponents.d.ts +13 -0
- package/dist/core/lazyComponents.js +73 -0
- package/dist/core/router.d.ts +55 -0
- package/dist/core/router.js +424 -0
- package/dist/core/state.d.ts +18 -0
- package/dist/core/state.js +153 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +11 -0
- package/dist/utils/cacheBuster.d.ts +9 -0
- package/dist/utils/cacheBuster.js +12 -0
- package/dist/utils/dom.d.ts +16 -0
- package/dist/utils/dom.js +70 -0
- package/dist/utils/events.d.ts +20 -0
- package/dist/utils/events.js +80 -0
- package/dist/utils/templates.d.ts +2 -0
- package/dist/utils/templates.js +2 -0
- package/package.json +53 -0
- package/src/styles/base.css +40 -0
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NcDiv Component - Responsive Container
|
|
3
|
+
*
|
|
4
|
+
* A flexible container component with built-in responsive grid/flex layouts
|
|
5
|
+
*
|
|
6
|
+
* Attributes:
|
|
7
|
+
* - layout: 'grid' | 'flex' | 'grid-auto' | 'block' (default: 'grid-auto')
|
|
8
|
+
* - cols: '1' | '2' | '3' | '4' (for grid layout)
|
|
9
|
+
* - direction: 'row' | 'column' (for flex layout)
|
|
10
|
+
* - gap: 'sm' | 'md' | 'lg' | 'xl' (default: 'md')
|
|
11
|
+
* - width: 'full' | 'three-quarters' | 'half' | 'quarter' (default: 'full')
|
|
12
|
+
* - justify: 'start' | 'center' | 'end' | 'between' | 'around' | 'evenly' (for flex/grid)
|
|
13
|
+
* - align: 'start' | 'center' | 'end' | 'stretch' | 'baseline' (for flex/grid)
|
|
14
|
+
*
|
|
15
|
+
* Usage:
|
|
16
|
+
* <nc-div layout="grid-auto">
|
|
17
|
+
* Card 1</nc-card>
|
|
18
|
+
* Card 2</nc-card>
|
|
19
|
+
* </nc-div>
|
|
20
|
+
*
|
|
21
|
+
* <nc-div layout="grid" cols="3">
|
|
22
|
+
* Card 1</nc-card>
|
|
23
|
+
* Card 2</nc-card>
|
|
24
|
+
* Card 3</nc-card>
|
|
25
|
+
* </nc-div>
|
|
26
|
+
*
|
|
27
|
+
* <nc-div layout="flex" direction="row" gap="lg" justify="center" align="center">
|
|
28
|
+
* Flexbox Item 1</nc-card>
|
|
29
|
+
* Flexbox Item 2</nc-card>
|
|
30
|
+
* </nc-div>
|
|
31
|
+
*/
|
|
32
|
+
import { Component, defineComponent } from '../core/component.js';
|
|
33
|
+
export class NcDiv extends Component {
|
|
34
|
+
static useShadowDOM = true;
|
|
35
|
+
// ═══ Define dropdown options for dev tools ═══
|
|
36
|
+
static attributeOptions = {
|
|
37
|
+
layout: ['grid-auto', 'grid', 'flex', 'block'],
|
|
38
|
+
cols: ['1', '2', '3', '4'],
|
|
39
|
+
direction: ['row', 'column'],
|
|
40
|
+
gap: ['sm', 'md', 'lg', 'xl'],
|
|
41
|
+
width: ['full', 'three-quarters', 'half', 'quarter'],
|
|
42
|
+
justify: ['start', 'center', 'end', 'between', 'around', 'evenly'],
|
|
43
|
+
align: ['start', 'center', 'end', 'stretch', 'baseline']
|
|
44
|
+
};
|
|
45
|
+
// ═══ Conditional visibility for attributes based on layout ═══
|
|
46
|
+
static attributeConditions = {
|
|
47
|
+
cols: (element) => {
|
|
48
|
+
const layout = element.getAttribute('layout') || 'grid-auto';
|
|
49
|
+
return layout === 'grid';
|
|
50
|
+
},
|
|
51
|
+
direction: (element) => {
|
|
52
|
+
const layout = element.getAttribute('layout') || 'grid-auto';
|
|
53
|
+
return layout === 'flex';
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
// ═══ Attributes become editable in dev tools sidebar ═══
|
|
57
|
+
static get observedAttributes() {
|
|
58
|
+
return ['layout', 'cols', 'direction', 'gap', 'width', 'justify', 'align'];
|
|
59
|
+
}
|
|
60
|
+
constructor() {
|
|
61
|
+
super();
|
|
62
|
+
}
|
|
63
|
+
template() {
|
|
64
|
+
return `
|
|
65
|
+
<style>
|
|
66
|
+
:host {
|
|
67
|
+
display: block;
|
|
68
|
+
width: 100%;
|
|
69
|
+
box-sizing: border-box;
|
|
70
|
+
margin: var(--nc-spacing-lg) 0 !important;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/* Layout: Auto-fit Grid (Recommended) */
|
|
74
|
+
:host([layout="grid-auto"]) {
|
|
75
|
+
display: grid;
|
|
76
|
+
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/* Layout: Fixed Grid */
|
|
80
|
+
:host([layout="grid"]) {
|
|
81
|
+
display: grid;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
:host([layout="grid"][cols="1"]) {
|
|
85
|
+
grid-template-columns: repeat(1, minmax(0, 1fr));
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
:host([layout="grid"][cols="2"]) {
|
|
89
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
:host([layout="grid"][cols="3"]) {
|
|
93
|
+
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
:host([layout="grid"][cols="4"]) {
|
|
97
|
+
grid-template-columns: repeat(4, minmax(0, 1fr));
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/* Layout: Flexbox */
|
|
101
|
+
:host([layout="flex"]) {
|
|
102
|
+
display: flex;
|
|
103
|
+
flex-wrap: wrap;
|
|
104
|
+
flex-direction: column; /* Default to column (vertical stack) */
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/* Flex Direction */
|
|
108
|
+
:host([layout="flex"][direction="row"]) {
|
|
109
|
+
flex-direction: row;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
:host([layout="flex"][direction="column"]) {
|
|
113
|
+
flex-direction: column;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/* Row layout: children can grow with 300px basis */
|
|
117
|
+
:host([layout="flex"][direction="row"]) ::slotted(*) {
|
|
118
|
+
flex: 1 1 300px;
|
|
119
|
+
min-width: 0;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/* Column layout (default): children size to content */
|
|
123
|
+
:host([layout="flex"]) ::slotted(*),
|
|
124
|
+
:host([layout="flex"][direction="column"]) ::slotted(*) {
|
|
125
|
+
flex: 0 1 auto;
|
|
126
|
+
min-width: 0;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/* Layout: Block */
|
|
130
|
+
:host([layout="block"]) {
|
|
131
|
+
display: block;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/* Gap Sizes */
|
|
135
|
+
:host([gap="sm"]) {
|
|
136
|
+
gap: var(--nc-spacing-sm);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
:host([gap="md"]) {
|
|
140
|
+
gap: var(--nc-spacing-md);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
:host([gap="lg"]) {
|
|
144
|
+
gap: var(--nc-spacing-lg);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
:host([gap="xl"]) {
|
|
148
|
+
gap: var(--nc-spacing-xl);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/* Justify Content - Works for both Flex & Grid */
|
|
152
|
+
:host([justify="start"]) {
|
|
153
|
+
justify-content: flex-start;
|
|
154
|
+
justify-items: start;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
:host([justify="center"]) {
|
|
158
|
+
justify-content: center;
|
|
159
|
+
justify-items: center;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
:host([justify="end"]) {
|
|
163
|
+
justify-content: flex-end;
|
|
164
|
+
justify-items: end;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
:host([justify="between"]) {
|
|
168
|
+
justify-content: space-between;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
:host([justify="around"]) {
|
|
172
|
+
justify-content: space-around;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
:host([justify="evenly"]) {
|
|
176
|
+
justify-content: space-evenly;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/* Align Items - Works for both Flex & Grid */
|
|
180
|
+
:host([align="start"]) {
|
|
181
|
+
align-items: flex-start;
|
|
182
|
+
align-content: flex-start;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
:host([align="center"]) {
|
|
186
|
+
align-items: center;
|
|
187
|
+
align-content: center;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
:host([align="end"]) {
|
|
191
|
+
align-items: flex-end;
|
|
192
|
+
align-content: flex-end;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
:host([align="stretch"]) {
|
|
196
|
+
align-items: stretch;
|
|
197
|
+
align-content: stretch;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
:host([align="baseline"]) {
|
|
201
|
+
align-items: baseline;
|
|
202
|
+
align-content: baseline;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/* Width Options */
|
|
206
|
+
:host([width="full"]) {
|
|
207
|
+
width: 100%;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
:host([width="three-quarters"]) {
|
|
211
|
+
width: 75%;
|
|
212
|
+
margin-left: auto;
|
|
213
|
+
margin-right: auto;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
:host([width="half"]) {
|
|
217
|
+
width: 50%;
|
|
218
|
+
margin-left: auto;
|
|
219
|
+
margin-right: auto;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
:host([width="quarter"]) {
|
|
223
|
+
width: 25%;
|
|
224
|
+
margin-left: auto;
|
|
225
|
+
margin-right: auto;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/* Responsive: Mobile */
|
|
229
|
+
@media (max-width: 768px) {
|
|
230
|
+
:host([layout="grid"][cols="2"]),
|
|
231
|
+
:host([layout="grid"][cols="3"]),
|
|
232
|
+
:host([layout="grid"][cols="4"]) {
|
|
233
|
+
grid-template-columns: repeat(1, minmax(0, 1fr));
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
:host([layout="grid-auto"]) {
|
|
237
|
+
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/* Full width on mobile for better UX */
|
|
241
|
+
:host([width="three-quarters"]),
|
|
242
|
+
:host([width="half"]),
|
|
243
|
+
:host([width="quarter"]) {
|
|
244
|
+
width: 100% !important;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/* Responsive: Tablet */
|
|
249
|
+
@media (min-width: 769px) and (max-width: 1024px) {
|
|
250
|
+
:host([layout="grid"][cols="3"]),
|
|
251
|
+
:host([layout="grid"][cols="4"]) {
|
|
252
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
</style>
|
|
256
|
+
|
|
257
|
+
<slot></slot>
|
|
258
|
+
`;
|
|
259
|
+
}
|
|
260
|
+
onMount() {
|
|
261
|
+
// Component logic here
|
|
262
|
+
}
|
|
263
|
+
// ═══ Makes changes instant in dev tools preview ═══
|
|
264
|
+
attributeChangedCallback(name, oldValue, newValue) {
|
|
265
|
+
if (oldValue !== newValue && this._mounted) {
|
|
266
|
+
this.render();
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
defineComponent('nc-div', NcDiv);
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Component } from '../core/component.js';
|
|
2
|
+
export declare class NcDivider extends Component {
|
|
3
|
+
static useShadowDOM: boolean;
|
|
4
|
+
static get observedAttributes(): string[];
|
|
5
|
+
template(): string;
|
|
6
|
+
attributeChangedCallback(name: string, oldValue: string, newValue: string): void;
|
|
7
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Component, defineComponent } from '../core/component.js';
|
|
2
|
+
export class NcDivider extends Component {
|
|
3
|
+
static useShadowDOM = true;
|
|
4
|
+
static get observedAttributes() {
|
|
5
|
+
return ['orientation', 'variant', 'label', 'thickness', 'color', 'spacing'];
|
|
6
|
+
}
|
|
7
|
+
template() {
|
|
8
|
+
const orientation = this.getAttribute('orientation') || 'horizontal';
|
|
9
|
+
const variant = this.getAttribute('variant') || 'solid';
|
|
10
|
+
const label = this.getAttribute('label') || '';
|
|
11
|
+
const thickness = this.getAttribute('thickness') || '1px';
|
|
12
|
+
const color = this.getAttribute('color') || 'var(--nc-border, #e5e7eb)';
|
|
13
|
+
const spacing = this.getAttribute('spacing') || (orientation === 'horizontal' ? 'var(--nc-spacing-md, 1rem) 0' : '0 var(--nc-spacing-md, 1rem)');
|
|
14
|
+
const isHorizontal = orientation === 'horizontal';
|
|
15
|
+
return `
|
|
16
|
+
<style>
|
|
17
|
+
:host {
|
|
18
|
+
display: ${isHorizontal ? 'block' : 'inline-flex'};
|
|
19
|
+
align-self: ${isHorizontal ? 'auto' : 'stretch'};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.divider {
|
|
23
|
+
display: flex;
|
|
24
|
+
align-items: center;
|
|
25
|
+
margin: ${spacing};
|
|
26
|
+
${isHorizontal ? 'width: 100%;' : 'flex-direction: column; height: 100%;'}
|
|
27
|
+
font-family: var(--nc-font-family);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.line {
|
|
31
|
+
${isHorizontal ? 'flex: 1; height: 0;' : 'flex: 1; width: 0;'}
|
|
32
|
+
border: none;
|
|
33
|
+
border-${isHorizontal ? 'top' : 'left'}: ${thickness} ${variant} ${color};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.label {
|
|
37
|
+
padding: ${isHorizontal ? '0 var(--nc-spacing-sm, 0.5rem)' : 'var(--nc-spacing-sm, 0.5rem) 0'};
|
|
38
|
+
font-size: var(--nc-font-size-xs, 0.75rem);
|
|
39
|
+
color: var(--nc-text-muted, #6b7280);
|
|
40
|
+
white-space: nowrap;
|
|
41
|
+
font-weight: var(--nc-font-weight-medium, 500);
|
|
42
|
+
text-transform: uppercase;
|
|
43
|
+
letter-spacing: 0.05em;
|
|
44
|
+
}
|
|
45
|
+
</style>
|
|
46
|
+
<div class="divider" role="separator" aria-orientation="${orientation}">
|
|
47
|
+
<span class="line"></span>
|
|
48
|
+
${label ? `<span class="label">${label}</span><span class="line"></span>` : ''}
|
|
49
|
+
</div>
|
|
50
|
+
`;
|
|
51
|
+
}
|
|
52
|
+
attributeChangedCallback(name, oldValue, newValue) {
|
|
53
|
+
if (oldValue !== newValue && this._mounted)
|
|
54
|
+
this.render();
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
defineComponent('nc-divider', NcDivider);
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NcDrawer Component
|
|
3
|
+
*
|
|
4
|
+
* Attributes:
|
|
5
|
+
* - open: boolean - visible state
|
|
6
|
+
* - placement: 'left'|'right'|'top'|'bottom' (default: 'right')
|
|
7
|
+
* - size: string - CSS width/height of the panel (default: '320px')
|
|
8
|
+
* - overlay: boolean - show backdrop overlay (default: true)
|
|
9
|
+
* - close-on-overlay: boolean - click overlay to close (default: true)
|
|
10
|
+
* - no-close-btn: boolean - hide the built-in close button
|
|
11
|
+
*
|
|
12
|
+
* Slots:
|
|
13
|
+
* - header - drawer header area
|
|
14
|
+
* - (default) - drawer body content
|
|
15
|
+
* - footer - drawer footer area
|
|
16
|
+
*
|
|
17
|
+
* Events:
|
|
18
|
+
* - open: CustomEvent - after drawer opens
|
|
19
|
+
* - close: CustomEvent - after drawer closes
|
|
20
|
+
*
|
|
21
|
+
* Usage:
|
|
22
|
+
* <nc-drawer id="nav-drawer" placement="left">
|
|
23
|
+
* <span slot="header">Navigation</span>
|
|
24
|
+
* <p>Links go here</p>
|
|
25
|
+
* </nc-drawer>
|
|
26
|
+
*
|
|
27
|
+
* document.getElementById('nav-drawer').setAttribute('open', '');
|
|
28
|
+
*/
|
|
29
|
+
import { Component } from '../core/component.js';
|
|
30
|
+
export declare class NcDrawer extends Component {
|
|
31
|
+
static useShadowDOM: boolean;
|
|
32
|
+
static get observedAttributes(): string[];
|
|
33
|
+
template(): string;
|
|
34
|
+
onMount(): void;
|
|
35
|
+
private _bindEvents;
|
|
36
|
+
private _onKeydown;
|
|
37
|
+
private _close;
|
|
38
|
+
onUnmount(): void;
|
|
39
|
+
attributeChangedCallback(name: string, oldValue: string, newValue: string): void;
|
|
40
|
+
}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NcDrawer Component
|
|
3
|
+
*
|
|
4
|
+
* Attributes:
|
|
5
|
+
* - open: boolean - visible state
|
|
6
|
+
* - placement: 'left'|'right'|'top'|'bottom' (default: 'right')
|
|
7
|
+
* - size: string - CSS width/height of the panel (default: '320px')
|
|
8
|
+
* - overlay: boolean - show backdrop overlay (default: true)
|
|
9
|
+
* - close-on-overlay: boolean - click overlay to close (default: true)
|
|
10
|
+
* - no-close-btn: boolean - hide the built-in close button
|
|
11
|
+
*
|
|
12
|
+
* Slots:
|
|
13
|
+
* - header - drawer header area
|
|
14
|
+
* - (default) - drawer body content
|
|
15
|
+
* - footer - drawer footer area
|
|
16
|
+
*
|
|
17
|
+
* Events:
|
|
18
|
+
* - open: CustomEvent - after drawer opens
|
|
19
|
+
* - close: CustomEvent - after drawer closes
|
|
20
|
+
*
|
|
21
|
+
* Usage:
|
|
22
|
+
* <nc-drawer id="nav-drawer" placement="left">
|
|
23
|
+
* <span slot="header">Navigation</span>
|
|
24
|
+
* <p>Links go here</p>
|
|
25
|
+
* </nc-drawer>
|
|
26
|
+
*
|
|
27
|
+
* document.getElementById('nav-drawer').setAttribute('open', '');
|
|
28
|
+
*/
|
|
29
|
+
import { Component, defineComponent } from '../core/component.js';
|
|
30
|
+
export class NcDrawer extends Component {
|
|
31
|
+
static useShadowDOM = true;
|
|
32
|
+
static get observedAttributes() {
|
|
33
|
+
return ['open', 'placement', 'size', 'overlay', 'close-on-overlay', 'no-close-btn'];
|
|
34
|
+
}
|
|
35
|
+
template() {
|
|
36
|
+
const open = this.hasAttribute('open');
|
|
37
|
+
const placement = this.getAttribute('placement') || 'right';
|
|
38
|
+
const size = this.getAttribute('size') || '320px';
|
|
39
|
+
const showOverlay = !this.hasAttribute('overlay') || this.getAttribute('overlay') !== 'false';
|
|
40
|
+
const noCloseBtn = this.hasAttribute('no-close-btn');
|
|
41
|
+
const isHorizontal = placement === 'left' || placement === 'right';
|
|
42
|
+
const panelSize = isHorizontal
|
|
43
|
+
? `width: ${size}; height: 100%;`
|
|
44
|
+
: `height: ${size}; width: 100%;`;
|
|
45
|
+
const translateClosed = {
|
|
46
|
+
left: 'translateX(-100%)',
|
|
47
|
+
right: 'translateX(100%)',
|
|
48
|
+
top: 'translateY(-100%)',
|
|
49
|
+
bottom: 'translateY(100%)',
|
|
50
|
+
}[placement];
|
|
51
|
+
return `
|
|
52
|
+
<style>
|
|
53
|
+
:host { display: contents; }
|
|
54
|
+
|
|
55
|
+
.overlay {
|
|
56
|
+
position: fixed;
|
|
57
|
+
inset: 0;
|
|
58
|
+
background: rgba(0,0,0,.45);
|
|
59
|
+
z-index: 900;
|
|
60
|
+
opacity: ${open ? '1' : '0'};
|
|
61
|
+
pointer-events: ${open && showOverlay ? 'auto' : 'none'};
|
|
62
|
+
transition: opacity var(--nc-transition-base);
|
|
63
|
+
display: ${showOverlay ? 'block' : 'none'};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.panel {
|
|
67
|
+
position: fixed;
|
|
68
|
+
${placement}: 0;
|
|
69
|
+
${placement === 'left' || placement === 'right' ? 'top: 0;' : 'left: 0;'}
|
|
70
|
+
${panelSize}
|
|
71
|
+
background: var(--nc-bg);
|
|
72
|
+
box-shadow: var(--nc-shadow-xl, 0 20px 60px rgba(0,0,0,.3));
|
|
73
|
+
z-index: 901;
|
|
74
|
+
display: flex;
|
|
75
|
+
flex-direction: column;
|
|
76
|
+
transform: ${open ? 'none' : translateClosed};
|
|
77
|
+
transition: transform var(--nc-transition-base);
|
|
78
|
+
overflow: hidden;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.panel__header {
|
|
82
|
+
display: flex;
|
|
83
|
+
align-items: center;
|
|
84
|
+
justify-content: space-between;
|
|
85
|
+
padding: var(--nc-spacing-md) var(--nc-spacing-lg);
|
|
86
|
+
border-bottom: 1px solid var(--nc-border);
|
|
87
|
+
font-family: var(--nc-font-family);
|
|
88
|
+
font-weight: var(--nc-font-weight-semibold);
|
|
89
|
+
font-size: var(--nc-font-size-lg);
|
|
90
|
+
color: var(--nc-text);
|
|
91
|
+
flex-shrink: 0;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.panel__body {
|
|
95
|
+
flex: 1;
|
|
96
|
+
overflow-y: auto;
|
|
97
|
+
padding: var(--nc-spacing-lg);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.panel__footer {
|
|
101
|
+
padding: var(--nc-spacing-md) var(--nc-spacing-lg);
|
|
102
|
+
border-top: 1px solid var(--nc-border);
|
|
103
|
+
flex-shrink: 0;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.panel__footer:empty { display: none; }
|
|
107
|
+
|
|
108
|
+
.close-btn {
|
|
109
|
+
background: none;
|
|
110
|
+
border: none;
|
|
111
|
+
cursor: pointer;
|
|
112
|
+
padding: 4px;
|
|
113
|
+
color: var(--nc-text-muted);
|
|
114
|
+
border-radius: var(--nc-radius-sm, 4px);
|
|
115
|
+
display: flex;
|
|
116
|
+
transition: color var(--nc-transition-fast), background var(--nc-transition-fast);
|
|
117
|
+
}
|
|
118
|
+
.close-btn:hover { color: var(--nc-text); background: var(--nc-bg-secondary); }
|
|
119
|
+
</style>
|
|
120
|
+
|
|
121
|
+
${showOverlay ? `<div class="overlay" aria-hidden="true"></div>` : ''}
|
|
122
|
+
|
|
123
|
+
<div
|
|
124
|
+
class="panel"
|
|
125
|
+
role="dialog"
|
|
126
|
+
aria-modal="true"
|
|
127
|
+
aria-hidden="${!open}"
|
|
128
|
+
tabindex="-1"
|
|
129
|
+
>
|
|
130
|
+
<div class="panel__header">
|
|
131
|
+
<slot name="header"></slot>
|
|
132
|
+
${!noCloseBtn ? `
|
|
133
|
+
<button class="close-btn" type="button" aria-label="Close drawer">
|
|
134
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="none" width="18" height="18">
|
|
135
|
+
<path d="M3 3l10 10M13 3L3 13" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
|
|
136
|
+
</svg>
|
|
137
|
+
</button>` : ''}
|
|
138
|
+
</div>
|
|
139
|
+
<div class="panel__body">
|
|
140
|
+
<slot></slot>
|
|
141
|
+
</div>
|
|
142
|
+
<div class="panel__footer">
|
|
143
|
+
<slot name="footer"></slot>
|
|
144
|
+
</div>
|
|
145
|
+
</div>
|
|
146
|
+
`;
|
|
147
|
+
}
|
|
148
|
+
onMount() {
|
|
149
|
+
this._bindEvents();
|
|
150
|
+
}
|
|
151
|
+
_bindEvents() {
|
|
152
|
+
const closeBtn = this.$('.close-btn');
|
|
153
|
+
if (closeBtn) {
|
|
154
|
+
closeBtn.addEventListener('click', () => this._close());
|
|
155
|
+
}
|
|
156
|
+
const overlay = this.$('.overlay');
|
|
157
|
+
if (overlay) {
|
|
158
|
+
overlay.addEventListener('click', () => {
|
|
159
|
+
if (!this.hasAttribute('close-on-overlay') || this.getAttribute('close-on-overlay') !== 'false') {
|
|
160
|
+
this._close();
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
// Close on Escape
|
|
165
|
+
this._onKeydown = (e) => {
|
|
166
|
+
if (e.key === 'Escape' && this.hasAttribute('open'))
|
|
167
|
+
this._close();
|
|
168
|
+
};
|
|
169
|
+
document.addEventListener('keydown', this._onKeydown);
|
|
170
|
+
}
|
|
171
|
+
_onKeydown = null;
|
|
172
|
+
_close() {
|
|
173
|
+
this.removeAttribute('open');
|
|
174
|
+
this.dispatchEvent(new CustomEvent('close', { bubbles: true, composed: true }));
|
|
175
|
+
}
|
|
176
|
+
onUnmount() {
|
|
177
|
+
if (this._onKeydown)
|
|
178
|
+
document.removeEventListener('keydown', this._onKeydown);
|
|
179
|
+
}
|
|
180
|
+
attributeChangedCallback(name, oldValue, newValue) {
|
|
181
|
+
if (oldValue === newValue)
|
|
182
|
+
return;
|
|
183
|
+
if (name === 'open' && this._mounted) {
|
|
184
|
+
const open = this.hasAttribute('open');
|
|
185
|
+
const panel = this.$('.panel');
|
|
186
|
+
const overlay = this.$('.overlay');
|
|
187
|
+
const placement = this.getAttribute('placement') || 'right';
|
|
188
|
+
const translateClosed = {
|
|
189
|
+
left: 'translateX(-100%)',
|
|
190
|
+
right: 'translateX(100%)',
|
|
191
|
+
top: 'translateY(-100%)',
|
|
192
|
+
bottom: 'translateY(100%)',
|
|
193
|
+
}[placement];
|
|
194
|
+
if (panel) {
|
|
195
|
+
panel.style.transform = open ? 'none' : (translateClosed ?? 'translateX(100%)');
|
|
196
|
+
panel.setAttribute('aria-hidden', String(!open));
|
|
197
|
+
if (open)
|
|
198
|
+
panel.focus();
|
|
199
|
+
}
|
|
200
|
+
if (overlay) {
|
|
201
|
+
overlay.style.opacity = open ? '1' : '0';
|
|
202
|
+
overlay.style.pointerEvents = open ? 'auto' : 'none';
|
|
203
|
+
}
|
|
204
|
+
// Lock body scroll while open
|
|
205
|
+
document.body.style.overflow = open ? 'hidden' : '';
|
|
206
|
+
this.dispatchEvent(new CustomEvent(open ? 'open' : 'close', {
|
|
207
|
+
bubbles: true, composed: true
|
|
208
|
+
}));
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
if (this._mounted) {
|
|
212
|
+
this.render();
|
|
213
|
+
this._bindEvents();
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
defineComponent('nc-drawer', NcDrawer);
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NcDropdown Component
|
|
3
|
+
*
|
|
4
|
+
* A generic trigger + floating-panel component. The trigger is whatever
|
|
5
|
+
* is in slot[name="trigger"]; the content panel is the default slot.
|
|
6
|
+
*
|
|
7
|
+
* Attributes:
|
|
8
|
+
* - open: boolean - visible state
|
|
9
|
+
* - placement: 'bottom-start'|'bottom-end'|'bottom'|'top-start'|'top-end'|'top' (default: 'bottom-start')
|
|
10
|
+
* - close-on-select: boolean - close when a [data-value] child is clicked (default: true)
|
|
11
|
+
* - disabled: boolean
|
|
12
|
+
* - offset: number - gap in px between trigger and panel (default: 6)
|
|
13
|
+
* - width: string - CSS width of panel (default: 'auto'; use 'trigger' to match trigger width)
|
|
14
|
+
*
|
|
15
|
+
* Events:
|
|
16
|
+
* - open: CustomEvent
|
|
17
|
+
* - close: CustomEvent
|
|
18
|
+
* - select: CustomEvent<{ value: string; label: string }> - when a [data-value] child is clicked
|
|
19
|
+
*
|
|
20
|
+
* Usage:
|
|
21
|
+
* <nc-dropdown>
|
|
22
|
+
* <nc-button slot="trigger">Options</nc-button>
|
|
23
|
+
* <nc-menu>
|
|
24
|
+
* <nc-menu-item data-value="edit">Edit</nc-menu-item>
|
|
25
|
+
* <nc-menu-item data-value="delete">Delete</nc-menu-item>
|
|
26
|
+
* </nc-menu>
|
|
27
|
+
* </nc-dropdown>
|
|
28
|
+
*/
|
|
29
|
+
import { Component } from '../core/component.js';
|
|
30
|
+
export declare class NcDropdown extends Component {
|
|
31
|
+
static useShadowDOM: boolean;
|
|
32
|
+
static get observedAttributes(): string[];
|
|
33
|
+
private _outsideClick;
|
|
34
|
+
template(): string;
|
|
35
|
+
onMount(): void;
|
|
36
|
+
private _bindEvents;
|
|
37
|
+
private _hookTrigger;
|
|
38
|
+
private _setOpen;
|
|
39
|
+
onUnmount(): void;
|
|
40
|
+
attributeChangedCallback(name: string, oldValue: string, newValue: string): void;
|
|
41
|
+
}
|