@nuralyui/layout 0.0.1
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.js +297 -0
- package/content.component.d.ts +35 -0
- package/content.component.js +47 -0
- package/content.style.d.ts +2 -0
- package/content.style.js +17 -0
- package/footer.component.d.ts +38 -0
- package/footer.component.js +60 -0
- package/footer.style.d.ts +2 -0
- package/footer.style.js +17 -0
- package/header.component.d.ts +39 -0
- package/header.component.js +61 -0
- package/header.style.d.ts +2 -0
- package/header.style.js +19 -0
- package/index.d.ts +8 -0
- package/index.js +7 -0
- package/layout.component.d.ts +50 -0
- package/layout.component.js +89 -0
- package/layout.style.d.ts +2 -0
- package/layout.style.js +23 -0
- package/layout.types.d.ts +75 -0
- package/layout.types.js +12 -0
- package/package.json +38 -0
- package/react.d.ts +14 -0
- package/react.js +37 -0
- package/sider.component.d.ts +116 -0
- package/sider.component.js +273 -0
- package/sider.style.d.ts +2 -0
- package/sider.style.js +104 -0
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { LitElement, html } from 'lit';
|
|
8
|
+
import { customElement, property, state } from 'lit/decorators.js';
|
|
9
|
+
import { classMap } from 'lit/directives/class-map.js';
|
|
10
|
+
import { NuralyUIBaseMixin } from '../../shared/base-mixin.js';
|
|
11
|
+
import { siderStyles } from './sider.style.js';
|
|
12
|
+
import { BREAKPOINT_VALUES, } from './layout.types.js';
|
|
13
|
+
/**
|
|
14
|
+
* # Sider Component
|
|
15
|
+
*
|
|
16
|
+
* The sidebar component with collapsible functionality, theme support, and responsive behavior.
|
|
17
|
+
* Must be placed inside a Layout component.
|
|
18
|
+
*
|
|
19
|
+
* @element nr-sider
|
|
20
|
+
*
|
|
21
|
+
* @slot - Default slot for sider content (usually navigation menu)
|
|
22
|
+
* @slot trigger - Custom trigger slot (overrides default trigger)
|
|
23
|
+
*
|
|
24
|
+
* @fires collapse - Fired when the sider is collapsed or expanded
|
|
25
|
+
* @fires breakpoint - Fired when the breakpoint is triggered
|
|
26
|
+
*
|
|
27
|
+
* @csspart sider - The sider container element
|
|
28
|
+
* @csspart trigger - The collapse trigger element
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```html
|
|
32
|
+
* <nr-layout has-sider>
|
|
33
|
+
* <nr-sider collapsible breakpoint="lg">
|
|
34
|
+
* <nav>Navigation Menu</nav>
|
|
35
|
+
* </nr-sider>
|
|
36
|
+
* <nr-content>Content</nr-content>
|
|
37
|
+
* </nr-layout>
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
let NrSiderElement = class NrSiderElement extends NuralyUIBaseMixin(LitElement) {
|
|
41
|
+
constructor() {
|
|
42
|
+
super(...arguments);
|
|
43
|
+
/**
|
|
44
|
+
* Current collapsed state (controlled)
|
|
45
|
+
*/
|
|
46
|
+
this.collapsed = false;
|
|
47
|
+
/**
|
|
48
|
+
* Width when collapsed. Set to 0 for a special trigger.
|
|
49
|
+
*/
|
|
50
|
+
this.collapsedWidth = 80;
|
|
51
|
+
/**
|
|
52
|
+
* Whether the sider can be collapsed
|
|
53
|
+
*/
|
|
54
|
+
this.collapsible = false;
|
|
55
|
+
/**
|
|
56
|
+
* Initial collapsed state (uncontrolled)
|
|
57
|
+
*/
|
|
58
|
+
this.defaultCollapsed = false;
|
|
59
|
+
/**
|
|
60
|
+
* Reverse the arrow direction (for right-side sider)
|
|
61
|
+
*/
|
|
62
|
+
this.reverseArrow = false;
|
|
63
|
+
/**
|
|
64
|
+
* Sider theme (light or dark)
|
|
65
|
+
*/
|
|
66
|
+
this.theme = "dark" /* SiderTheme.Dark */;
|
|
67
|
+
/**
|
|
68
|
+
* Custom trigger element. Set to null to hide trigger.
|
|
69
|
+
*/
|
|
70
|
+
this.trigger = 'default';
|
|
71
|
+
/**
|
|
72
|
+
* Sider width when expanded
|
|
73
|
+
*/
|
|
74
|
+
this.width = 200;
|
|
75
|
+
/**
|
|
76
|
+
* Custom styles for zero-width trigger
|
|
77
|
+
*/
|
|
78
|
+
this.zeroWidthTriggerStyle = '';
|
|
79
|
+
/**
|
|
80
|
+
* Internal state for tracking if breakpoint is active
|
|
81
|
+
*/
|
|
82
|
+
this.belowBreakpoint = false;
|
|
83
|
+
}
|
|
84
|
+
connectedCallback() {
|
|
85
|
+
super.connectedCallback();
|
|
86
|
+
// Set initial collapsed state
|
|
87
|
+
if (this.defaultCollapsed && !this.hasAttribute('collapsed')) {
|
|
88
|
+
this.collapsed = true;
|
|
89
|
+
}
|
|
90
|
+
// Setup resize observer for breakpoint
|
|
91
|
+
if (this.breakpoint) {
|
|
92
|
+
this.setupResizeObserver();
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
disconnectedCallback() {
|
|
96
|
+
var _a;
|
|
97
|
+
super.disconnectedCallback();
|
|
98
|
+
(_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
|
|
99
|
+
}
|
|
100
|
+
updated(changedProperties) {
|
|
101
|
+
var _a;
|
|
102
|
+
super.updated(changedProperties);
|
|
103
|
+
if (changedProperties.has('breakpoint')) {
|
|
104
|
+
(_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
|
|
105
|
+
if (this.breakpoint) {
|
|
106
|
+
this.setupResizeObserver();
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Setup ResizeObserver for responsive breakpoint behavior
|
|
112
|
+
*/
|
|
113
|
+
setupResizeObserver() {
|
|
114
|
+
if (!this.breakpoint)
|
|
115
|
+
return;
|
|
116
|
+
const breakpointValue = BREAKPOINT_VALUES[this.breakpoint];
|
|
117
|
+
this.resizeObserver = new ResizeObserver((entries) => {
|
|
118
|
+
for (const entry of entries) {
|
|
119
|
+
const width = entry.contentRect.width;
|
|
120
|
+
const shouldBeCollapsed = width < breakpointValue;
|
|
121
|
+
if (shouldBeCollapsed !== this.belowBreakpoint) {
|
|
122
|
+
this.belowBreakpoint = shouldBeCollapsed;
|
|
123
|
+
// Auto-collapse when below breakpoint
|
|
124
|
+
if (this.collapsible && shouldBeCollapsed !== this.collapsed) {
|
|
125
|
+
this.collapsed = shouldBeCollapsed;
|
|
126
|
+
this.dispatchCollapseEvent('responsive');
|
|
127
|
+
}
|
|
128
|
+
// Dispatch breakpoint event
|
|
129
|
+
this.dispatchBreakpointEvent(shouldBeCollapsed);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
// Observe the parent layout or document body
|
|
134
|
+
const target = this.closest('nr-layout') || document.body;
|
|
135
|
+
this.resizeObserver.observe(target);
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Toggle collapsed state
|
|
139
|
+
*/
|
|
140
|
+
toggleCollapse() {
|
|
141
|
+
this.collapsed = !this.collapsed;
|
|
142
|
+
this.dispatchCollapseEvent('clickTrigger');
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Dispatch collapse event
|
|
146
|
+
*/
|
|
147
|
+
dispatchCollapseEvent(type) {
|
|
148
|
+
this.dispatchEvent(new CustomEvent('collapse', {
|
|
149
|
+
detail: { collapsed: this.collapsed, type },
|
|
150
|
+
bubbles: true,
|
|
151
|
+
composed: true,
|
|
152
|
+
}));
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Dispatch breakpoint event
|
|
156
|
+
*/
|
|
157
|
+
dispatchBreakpointEvent(broken) {
|
|
158
|
+
this.dispatchEvent(new CustomEvent('breakpoint', {
|
|
159
|
+
detail: { broken },
|
|
160
|
+
bubbles: true,
|
|
161
|
+
composed: true,
|
|
162
|
+
}));
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Get the current width based on collapsed state
|
|
166
|
+
*/
|
|
167
|
+
getCurrentWidth() {
|
|
168
|
+
if (this.collapsed) {
|
|
169
|
+
return `${this.collapsedWidth}px`;
|
|
170
|
+
}
|
|
171
|
+
return typeof this.width === 'number' ? `${this.width}px` : this.width.toString();
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Render the collapse trigger
|
|
175
|
+
*/
|
|
176
|
+
renderTrigger() {
|
|
177
|
+
if (this.trigger === null || !this.collapsible) {
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
// Check for custom trigger slot
|
|
181
|
+
const hasCustomTrigger = this.querySelector('[slot="trigger"]');
|
|
182
|
+
if (hasCustomTrigger) {
|
|
183
|
+
return html `<slot name="trigger"></slot>`;
|
|
184
|
+
}
|
|
185
|
+
// Zero-width trigger (special trigger when collapsedWidth is 0)
|
|
186
|
+
if (this.collapsedWidth === 0 && this.collapsed) {
|
|
187
|
+
return html `
|
|
188
|
+
<div
|
|
189
|
+
class="nr-sider-zero-width-trigger"
|
|
190
|
+
part="trigger"
|
|
191
|
+
style=${this.zeroWidthTriggerStyle}
|
|
192
|
+
@click=${this.toggleCollapse}
|
|
193
|
+
>
|
|
194
|
+
<span class="trigger-icon">${this.reverseArrow ? '◀' : '▶'}</span>
|
|
195
|
+
</div>
|
|
196
|
+
`;
|
|
197
|
+
}
|
|
198
|
+
// Default trigger
|
|
199
|
+
return html `
|
|
200
|
+
<div
|
|
201
|
+
class="nr-sider-trigger"
|
|
202
|
+
part="trigger"
|
|
203
|
+
@click=${this.toggleCollapse}
|
|
204
|
+
>
|
|
205
|
+
<span class="trigger-icon">
|
|
206
|
+
${this.collapsed
|
|
207
|
+
? (this.reverseArrow ? '◀' : '▶')
|
|
208
|
+
: (this.reverseArrow ? '▶' : '◀')}
|
|
209
|
+
</span>
|
|
210
|
+
</div>
|
|
211
|
+
`;
|
|
212
|
+
}
|
|
213
|
+
render() {
|
|
214
|
+
const classes = {
|
|
215
|
+
'nr-sider': true,
|
|
216
|
+
'nr-sider-collapsed': this.collapsed,
|
|
217
|
+
'nr-sider-has-trigger': this.collapsible && this.trigger !== null,
|
|
218
|
+
'nr-sider-below-breakpoint': this.belowBreakpoint,
|
|
219
|
+
'nr-sider-zero-width': this.collapsed && this.collapsedWidth === 0,
|
|
220
|
+
};
|
|
221
|
+
return html `
|
|
222
|
+
<aside
|
|
223
|
+
class=${classMap(classes)}
|
|
224
|
+
part="sider"
|
|
225
|
+
style="width: ${this.getCurrentWidth()}; flex: 0 0 ${this.getCurrentWidth()};"
|
|
226
|
+
>
|
|
227
|
+
<div class="nr-sider-children">
|
|
228
|
+
<slot></slot>
|
|
229
|
+
</div>
|
|
230
|
+
${this.renderTrigger()}
|
|
231
|
+
</aside>
|
|
232
|
+
`;
|
|
233
|
+
}
|
|
234
|
+
};
|
|
235
|
+
NrSiderElement.styles = siderStyles;
|
|
236
|
+
__decorate([
|
|
237
|
+
property({ type: String })
|
|
238
|
+
], NrSiderElement.prototype, "breakpoint", void 0);
|
|
239
|
+
__decorate([
|
|
240
|
+
property({ type: Boolean, reflect: true })
|
|
241
|
+
], NrSiderElement.prototype, "collapsed", void 0);
|
|
242
|
+
__decorate([
|
|
243
|
+
property({ type: Number, attribute: 'collapsed-width' })
|
|
244
|
+
], NrSiderElement.prototype, "collapsedWidth", void 0);
|
|
245
|
+
__decorate([
|
|
246
|
+
property({ type: Boolean })
|
|
247
|
+
], NrSiderElement.prototype, "collapsible", void 0);
|
|
248
|
+
__decorate([
|
|
249
|
+
property({ type: Boolean, attribute: 'default-collapsed' })
|
|
250
|
+
], NrSiderElement.prototype, "defaultCollapsed", void 0);
|
|
251
|
+
__decorate([
|
|
252
|
+
property({ type: Boolean, attribute: 'reverse-arrow' })
|
|
253
|
+
], NrSiderElement.prototype, "reverseArrow", void 0);
|
|
254
|
+
__decorate([
|
|
255
|
+
property({ type: String, reflect: true })
|
|
256
|
+
], NrSiderElement.prototype, "theme", void 0);
|
|
257
|
+
__decorate([
|
|
258
|
+
property({ type: String })
|
|
259
|
+
], NrSiderElement.prototype, "trigger", void 0);
|
|
260
|
+
__decorate([
|
|
261
|
+
property({ type: String })
|
|
262
|
+
], NrSiderElement.prototype, "width", void 0);
|
|
263
|
+
__decorate([
|
|
264
|
+
property({ type: String, attribute: 'zero-width-trigger-style' })
|
|
265
|
+
], NrSiderElement.prototype, "zeroWidthTriggerStyle", void 0);
|
|
266
|
+
__decorate([
|
|
267
|
+
state()
|
|
268
|
+
], NrSiderElement.prototype, "belowBreakpoint", void 0);
|
|
269
|
+
NrSiderElement = __decorate([
|
|
270
|
+
customElement('nr-sider')
|
|
271
|
+
], NrSiderElement);
|
|
272
|
+
export { NrSiderElement };
|
|
273
|
+
//# sourceMappingURL=sider.component.js.map
|
package/sider.style.d.ts
ADDED
package/sider.style.js
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { css } from 'lit';
|
|
2
|
+
export const siderStyles = css `
|
|
3
|
+
:host {
|
|
4
|
+
display: block;
|
|
5
|
+
position: relative;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.nr-sider {
|
|
9
|
+
position: relative;
|
|
10
|
+
display: flex;
|
|
11
|
+
flex-direction: column;
|
|
12
|
+
min-width: 0;
|
|
13
|
+
background: var(--nuraly-layout-sider-background);
|
|
14
|
+
color: var(--nuraly-layout-sider-text);
|
|
15
|
+
border-right: 1px solid var(--nuraly-layout-sider-border);
|
|
16
|
+
transition: var(--nuraly-layout-sider-transition);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
:host([theme='light']) .nr-sider {
|
|
20
|
+
background: var(--nuraly-layout-sider-light-background);
|
|
21
|
+
color: var(--nuraly-layout-sider-light-text);
|
|
22
|
+
border-right: 1px solid var(--nuraly-layout-sider-light-border);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.nr-sider-children {
|
|
26
|
+
flex: 1;
|
|
27
|
+
min-height: 0;
|
|
28
|
+
overflow: auto;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.nr-sider-trigger {
|
|
32
|
+
position: absolute;
|
|
33
|
+
bottom: 0;
|
|
34
|
+
left: 0;
|
|
35
|
+
right: 0;
|
|
36
|
+
height: var(--nuraly-layout-trigger-height);
|
|
37
|
+
display: flex;
|
|
38
|
+
align-items: center;
|
|
39
|
+
justify-content: center;
|
|
40
|
+
background: var(--nuraly-layout-trigger-background);
|
|
41
|
+
color: var(--nuraly-layout-trigger-text);
|
|
42
|
+
cursor: pointer;
|
|
43
|
+
transition: var(--nuraly-layout-transition);
|
|
44
|
+
border-top: 1px solid var(--nuraly-layout-trigger-border);
|
|
45
|
+
border-radius: var(--nuraly-layout-trigger-border-radius);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
:host([theme='light']) .nr-sider-trigger {
|
|
49
|
+
background: var(--nuraly-layout-trigger-light-background);
|
|
50
|
+
color: var(--nuraly-layout-trigger-light-text);
|
|
51
|
+
border-top: 1px solid var(--nuraly-layout-trigger-light-border);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.nr-sider-trigger:hover {
|
|
55
|
+
background: var(--nuraly-layout-trigger-background-hover);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
:host([theme='light']) .nr-sider-trigger:hover {
|
|
59
|
+
background: var(--nuraly-layout-trigger-light-background-hover);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.nr-sider-zero-width-trigger {
|
|
63
|
+
position: absolute;
|
|
64
|
+
top: 64px;
|
|
65
|
+
right: calc(-1 * var(--nuraly-layout-zero-trigger-width));
|
|
66
|
+
width: var(--nuraly-layout-zero-trigger-width);
|
|
67
|
+
height: var(--nuraly-layout-zero-trigger-height);
|
|
68
|
+
display: flex;
|
|
69
|
+
align-items: center;
|
|
70
|
+
justify-content: center;
|
|
71
|
+
background: var(--nuraly-layout-zero-trigger-background);
|
|
72
|
+
color: var(--nuraly-layout-zero-trigger-text);
|
|
73
|
+
cursor: pointer;
|
|
74
|
+
transition: var(--nuraly-layout-transition);
|
|
75
|
+
border-radius: var(--nuraly-layout-zero-trigger-border-radius);
|
|
76
|
+
box-shadow: var(--nuraly-layout-zero-trigger-shadow);
|
|
77
|
+
z-index: 1;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
:host([theme='light']) .nr-sider-zero-width-trigger {
|
|
81
|
+
background: var(--nuraly-layout-zero-trigger-background);
|
|
82
|
+
color: var(--nuraly-layout-zero-trigger-text);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.nr-sider-zero-width-trigger:hover {
|
|
86
|
+
background: var(--nuraly-layout-zero-trigger-background-hover);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.trigger-icon {
|
|
90
|
+
font-size: 16px;
|
|
91
|
+
line-height: 1;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.nr-sider-collapsed {
|
|
95
|
+
overflow: hidden;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.nr-sider-zero-width {
|
|
99
|
+
width: 0 !important;
|
|
100
|
+
min-width: 0 !important;
|
|
101
|
+
flex: 0 0 0 !important;
|
|
102
|
+
}
|
|
103
|
+
`;
|
|
104
|
+
//# sourceMappingURL=sider.style.js.map
|