@qwickapps/react-framework 1.3.2 → 1.3.4
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 +326 -0
- package/dist/components/AccessibilityProvider.d.ts +64 -0
- package/dist/components/AccessibilityProvider.d.ts.map +1 -0
- package/dist/components/Breadcrumbs.d.ts +39 -0
- package/dist/components/Breadcrumbs.d.ts.map +1 -0
- package/dist/components/ErrorBoundary.d.ts +39 -0
- package/dist/components/ErrorBoundary.d.ts.map +1 -0
- package/dist/components/QwickApp.d.ts.map +1 -1
- package/dist/components/forms/FormBlock.d.ts +1 -1
- package/dist/components/forms/FormBlock.d.ts.map +1 -1
- package/dist/components/index.d.ts +3 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/input/SwitchInputField.d.ts +28 -0
- package/dist/components/input/SwitchInputField.d.ts.map +1 -0
- package/dist/components/input/index.d.ts +2 -0
- package/dist/components/input/index.d.ts.map +1 -1
- package/dist/components/layout/CollapsibleLayout/CollapsibleLayout.d.ts +34 -0
- package/dist/components/layout/CollapsibleLayout/CollapsibleLayout.d.ts.map +1 -0
- package/dist/components/layout/CollapsibleLayout/index.d.ts +9 -0
- package/dist/components/layout/CollapsibleLayout/index.d.ts.map +1 -0
- package/dist/components/layout/index.d.ts +2 -0
- package/dist/components/layout/index.d.ts.map +1 -1
- package/dist/index.bundled.css +12 -0
- package/dist/index.esm.js +1678 -25
- package/dist/index.js +1689 -21
- package/dist/schemas/CollapsibleLayoutSchema.d.ts +31 -0
- package/dist/schemas/CollapsibleLayoutSchema.d.ts.map +1 -0
- package/dist/schemas/SwitchInputFieldSchema.d.ts +18 -0
- package/dist/schemas/SwitchInputFieldSchema.d.ts.map +1 -0
- package/dist/types/CollapsibleLayout.d.ts +142 -0
- package/dist/types/CollapsibleLayout.d.ts.map +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/AccessibilityProvider.tsx +466 -0
- package/src/components/Breadcrumbs.tsx +223 -0
- package/src/components/ErrorBoundary.tsx +216 -0
- package/src/components/QwickApp.tsx +17 -11
- package/src/components/__tests__/AccessibilityProvider.test.tsx +330 -0
- package/src/components/__tests__/Breadcrumbs.test.tsx +268 -0
- package/src/components/__tests__/ErrorBoundary.test.tsx +163 -0
- package/src/components/forms/FormBlock.tsx +2 -2
- package/src/components/index.ts +3 -0
- package/src/components/input/SwitchInputField.tsx +165 -0
- package/src/components/input/index.ts +2 -0
- package/src/components/layout/CollapsibleLayout/CollapsibleLayout.tsx +554 -0
- package/src/components/layout/CollapsibleLayout/__tests__/CollapsibleLayout.test.tsx +1469 -0
- package/src/components/layout/CollapsibleLayout/index.tsx +17 -0
- package/src/components/layout/index.ts +4 -1
- package/src/components/pages/FormPage.tsx +1 -1
- package/src/schemas/CollapsibleLayoutSchema.ts +276 -0
- package/src/schemas/SwitchInputFieldSchema.ts +99 -0
- package/src/stories/AccessibilityProvider.stories.tsx +284 -0
- package/src/stories/Breadcrumbs.stories.tsx +304 -0
- package/src/stories/CollapsibleLayout.stories.tsx +1566 -0
- package/src/stories/ErrorBoundary.stories.tsx +159 -0
- package/src/types/CollapsibleLayout.ts +231 -0
- package/src/types/index.ts +1 -0
- package/dist/schemas/Builders.d.ts +0 -7
- package/dist/schemas/Builders.d.ts.map +0 -1
- package/dist/schemas/types.d.ts +0 -7
- package/dist/schemas/types.d.ts.map +0 -1
- package/dist/types/DataBinding.d.ts +0 -7
- package/dist/types/DataBinding.d.ts.map +0 -1
- package/dist/types/DataProvider.d.ts +0 -7
- package/dist/types/DataProvider.d.ts.map +0 -1
package/dist/index.js
CHANGED
|
@@ -15336,6 +15336,689 @@ const GridCell = props => {
|
|
|
15336
15336
|
};
|
|
15337
15337
|
GridCell.displayName = 'GridCell';
|
|
15338
15338
|
|
|
15339
|
+
/**
|
|
15340
|
+
* CollapsibleLayout Schema - Data model for collapsible layout component
|
|
15341
|
+
*
|
|
15342
|
+
* Advanced expandable/collapsible container with header controls, animations,
|
|
15343
|
+
* content management, and state persistence capabilities.
|
|
15344
|
+
*
|
|
15345
|
+
* Copyright (c) 2025 QwickApps.com. All rights reserved.
|
|
15346
|
+
*/
|
|
15347
|
+
let CollapsibleLayoutModel = class CollapsibleLayoutModel extends schema.Model {};
|
|
15348
|
+
__decorate([schema.Field({
|
|
15349
|
+
defaultValue: false
|
|
15350
|
+
}), schema.Editor({
|
|
15351
|
+
field_type: schema.FieldType.BOOLEAN,
|
|
15352
|
+
label: 'Collapsed',
|
|
15353
|
+
description: 'Whether the layout is currently collapsed'
|
|
15354
|
+
}), classValidator.IsOptional(), classValidator.IsBoolean(), __metadata("design:type", Boolean)], CollapsibleLayoutModel.prototype, "collapsed", void 0);
|
|
15355
|
+
__decorate([schema.Field({
|
|
15356
|
+
defaultValue: false
|
|
15357
|
+
}), schema.Editor({
|
|
15358
|
+
field_type: schema.FieldType.BOOLEAN,
|
|
15359
|
+
label: 'Default Collapsed',
|
|
15360
|
+
description: 'Initial collapsed state for uncontrolled usage'
|
|
15361
|
+
}), classValidator.IsOptional(), classValidator.IsBoolean(), __metadata("design:type", Boolean)], CollapsibleLayoutModel.prototype, "defaultCollapsed", void 0);
|
|
15362
|
+
__decorate([schema.Field(), schema.Editor({
|
|
15363
|
+
field_type: schema.FieldType.TEXT,
|
|
15364
|
+
label: 'Title',
|
|
15365
|
+
description: 'Main title displayed in the header',
|
|
15366
|
+
placeholder: 'Enter title...'
|
|
15367
|
+
}), classValidator.IsOptional(), classValidator.IsString(), __metadata("design:type", String)], CollapsibleLayoutModel.prototype, "title", void 0);
|
|
15368
|
+
__decorate([schema.Field(), schema.Editor({
|
|
15369
|
+
field_type: schema.FieldType.TEXT,
|
|
15370
|
+
label: 'Subtitle',
|
|
15371
|
+
description: 'Secondary text displayed below the title',
|
|
15372
|
+
placeholder: 'Enter subtitle...'
|
|
15373
|
+
}), classValidator.IsOptional(), classValidator.IsString(), __metadata("design:type", String)], CollapsibleLayoutModel.prototype, "subtitle", void 0);
|
|
15374
|
+
__decorate([schema.Field(), schema.Editor({
|
|
15375
|
+
field_type: schema.FieldType.TEXT,
|
|
15376
|
+
label: 'Lead Icon',
|
|
15377
|
+
description: 'Icon displayed before the title (icon identifier or HTML)',
|
|
15378
|
+
placeholder: 'Icon identifier...'
|
|
15379
|
+
}), classValidator.IsOptional(), classValidator.IsString(), __metadata("design:type", String)], CollapsibleLayoutModel.prototype, "leadIcon", void 0);
|
|
15380
|
+
__decorate([schema.Field(), schema.Editor({
|
|
15381
|
+
field_type: schema.FieldType.TEXTAREA,
|
|
15382
|
+
label: 'Header Actions',
|
|
15383
|
+
description: 'Additional controls displayed in header (HTML/React content)',
|
|
15384
|
+
placeholder: 'Enter header actions HTML...'
|
|
15385
|
+
}), classValidator.IsOptional(), classValidator.IsString(), __metadata("design:type", String)], CollapsibleLayoutModel.prototype, "headerActions", void 0);
|
|
15386
|
+
__decorate([schema.Field(), schema.Editor({
|
|
15387
|
+
field_type: schema.FieldType.TEXTAREA,
|
|
15388
|
+
label: 'Collapsed View',
|
|
15389
|
+
description: 'Summary content shown when collapsed (HTML supported)',
|
|
15390
|
+
placeholder: 'Enter collapsed view content...'
|
|
15391
|
+
}), classValidator.IsOptional(), classValidator.IsString(), __metadata("design:type", String)], CollapsibleLayoutModel.prototype, "collapsedView", void 0);
|
|
15392
|
+
__decorate([schema.Field(), schema.Editor({
|
|
15393
|
+
field_type: schema.FieldType.TEXTAREA,
|
|
15394
|
+
label: 'Content',
|
|
15395
|
+
description: 'Main content shown when expanded (HTML supported)',
|
|
15396
|
+
placeholder: 'Enter main content...'
|
|
15397
|
+
}), classValidator.IsOptional(), classValidator.IsString(), __metadata("design:type", String)], CollapsibleLayoutModel.prototype, "children", void 0);
|
|
15398
|
+
__decorate([schema.Field(), schema.Editor({
|
|
15399
|
+
field_type: schema.FieldType.TEXTAREA,
|
|
15400
|
+
label: 'Footer View',
|
|
15401
|
+
description: 'Always visible footer content (HTML supported)',
|
|
15402
|
+
placeholder: 'Enter footer content...'
|
|
15403
|
+
}), classValidator.IsOptional(), classValidator.IsString(), __metadata("design:type", String)], CollapsibleLayoutModel.prototype, "footerView", void 0);
|
|
15404
|
+
__decorate([schema.Field({
|
|
15405
|
+
defaultValue: 'header'
|
|
15406
|
+
}), schema.Editor({
|
|
15407
|
+
field_type: schema.FieldType.SELECT,
|
|
15408
|
+
label: 'Trigger Area',
|
|
15409
|
+
description: 'Area that responds to clicks for toggle functionality',
|
|
15410
|
+
validation: {
|
|
15411
|
+
options: [{
|
|
15412
|
+
label: 'Button Only',
|
|
15413
|
+
value: 'button'
|
|
15414
|
+
}, {
|
|
15415
|
+
label: 'Header Area',
|
|
15416
|
+
value: 'header'
|
|
15417
|
+
}, {
|
|
15418
|
+
label: 'Button and Header',
|
|
15419
|
+
value: 'both'
|
|
15420
|
+
}]
|
|
15421
|
+
}
|
|
15422
|
+
}), classValidator.IsOptional(), classValidator.IsIn(['button', 'header', 'both']), __metadata("design:type", String)], CollapsibleLayoutModel.prototype, "triggerArea", void 0);
|
|
15423
|
+
__decorate([schema.Field({
|
|
15424
|
+
defaultValue: 'slide'
|
|
15425
|
+
}), schema.Editor({
|
|
15426
|
+
field_type: schema.FieldType.SELECT,
|
|
15427
|
+
label: 'Animation Style',
|
|
15428
|
+
description: 'Animation variant for expand/collapse transitions',
|
|
15429
|
+
validation: {
|
|
15430
|
+
options: [{
|
|
15431
|
+
label: 'Fade',
|
|
15432
|
+
value: 'fade'
|
|
15433
|
+
}, {
|
|
15434
|
+
label: 'Slide',
|
|
15435
|
+
value: 'slide'
|
|
15436
|
+
}, {
|
|
15437
|
+
label: 'Scale',
|
|
15438
|
+
value: 'scale'
|
|
15439
|
+
}]
|
|
15440
|
+
}
|
|
15441
|
+
}), classValidator.IsOptional(), classValidator.IsIn(['fade', 'slide', 'scale']), __metadata("design:type", String)], CollapsibleLayoutModel.prototype, "animationStyle", void 0);
|
|
15442
|
+
__decorate([schema.Field({
|
|
15443
|
+
defaultValue: false
|
|
15444
|
+
}), schema.Editor({
|
|
15445
|
+
field_type: schema.FieldType.BOOLEAN,
|
|
15446
|
+
label: 'Persist State',
|
|
15447
|
+
description: 'Save collapse state in local storage'
|
|
15448
|
+
}), classValidator.IsOptional(), classValidator.IsBoolean(), __metadata("design:type", Boolean)], CollapsibleLayoutModel.prototype, "persistState", void 0);
|
|
15449
|
+
__decorate([schema.Field(), schema.Editor({
|
|
15450
|
+
field_type: schema.FieldType.TEXT,
|
|
15451
|
+
label: 'Collapsed Icon',
|
|
15452
|
+
description: 'Icon shown when content is collapsed (default: VisibilityIcon)',
|
|
15453
|
+
placeholder: 'Icon identifier...'
|
|
15454
|
+
}), classValidator.IsOptional(), classValidator.IsString(), __metadata("design:type", String)], CollapsibleLayoutModel.prototype, "collapsedIcon", void 0);
|
|
15455
|
+
__decorate([schema.Field(), schema.Editor({
|
|
15456
|
+
field_type: schema.FieldType.TEXT,
|
|
15457
|
+
label: 'Expanded Icon',
|
|
15458
|
+
description: 'Icon shown when content is expanded (default: VisibilityOffIcon)',
|
|
15459
|
+
placeholder: 'Icon identifier...'
|
|
15460
|
+
}), classValidator.IsOptional(), classValidator.IsString(), __metadata("design:type", String)], CollapsibleLayoutModel.prototype, "expandedIcon", void 0);
|
|
15461
|
+
__decorate([schema.Field({
|
|
15462
|
+
defaultValue: true
|
|
15463
|
+
}), schema.Editor({
|
|
15464
|
+
field_type: schema.FieldType.BOOLEAN,
|
|
15465
|
+
label: 'Show Divider',
|
|
15466
|
+
description: 'Show divider lines between header, content, and footer sections'
|
|
15467
|
+
}), classValidator.IsOptional(), classValidator.IsBoolean(), __metadata("design:type", Boolean)], CollapsibleLayoutModel.prototype, "showDivider", void 0);
|
|
15468
|
+
__decorate([schema.Field({
|
|
15469
|
+
defaultValue: 'default'
|
|
15470
|
+
}), schema.Editor({
|
|
15471
|
+
field_type: schema.FieldType.SELECT,
|
|
15472
|
+
label: 'Variant',
|
|
15473
|
+
description: 'Visual style variant for the layout container',
|
|
15474
|
+
validation: {
|
|
15475
|
+
options: [{
|
|
15476
|
+
label: 'Default',
|
|
15477
|
+
value: 'default'
|
|
15478
|
+
}, {
|
|
15479
|
+
label: 'Outlined',
|
|
15480
|
+
value: 'outlined'
|
|
15481
|
+
}, {
|
|
15482
|
+
label: 'Elevated',
|
|
15483
|
+
value: 'elevated'
|
|
15484
|
+
}, {
|
|
15485
|
+
label: 'Filled',
|
|
15486
|
+
value: 'filled'
|
|
15487
|
+
}]
|
|
15488
|
+
}
|
|
15489
|
+
}), classValidator.IsOptional(), classValidator.IsIn(['default', 'outlined', 'elevated', 'filled']), __metadata("design:type", String)], CollapsibleLayoutModel.prototype, "variant", void 0);
|
|
15490
|
+
__decorate([schema.Field({
|
|
15491
|
+
defaultValue: 'comfortable'
|
|
15492
|
+
}), schema.Editor({
|
|
15493
|
+
field_type: schema.FieldType.SELECT,
|
|
15494
|
+
label: 'Header Spacing',
|
|
15495
|
+
description: 'Padding/spacing within the header area',
|
|
15496
|
+
validation: {
|
|
15497
|
+
options: [{
|
|
15498
|
+
label: 'Compact',
|
|
15499
|
+
value: 'compact'
|
|
15500
|
+
}, {
|
|
15501
|
+
label: 'Comfortable',
|
|
15502
|
+
value: 'comfortable'
|
|
15503
|
+
}, {
|
|
15504
|
+
label: 'Spacious',
|
|
15505
|
+
value: 'spacious'
|
|
15506
|
+
}]
|
|
15507
|
+
}
|
|
15508
|
+
}), classValidator.IsOptional(), classValidator.IsIn(['compact', 'comfortable', 'spacious']), __metadata("design:type", String)], CollapsibleLayoutModel.prototype, "headerSpacing", void 0);
|
|
15509
|
+
__decorate([schema.Field({
|
|
15510
|
+
defaultValue: 'comfortable'
|
|
15511
|
+
}), schema.Editor({
|
|
15512
|
+
field_type: schema.FieldType.SELECT,
|
|
15513
|
+
label: 'Content Spacing',
|
|
15514
|
+
description: 'Padding/spacing within the content area',
|
|
15515
|
+
validation: {
|
|
15516
|
+
options: [{
|
|
15517
|
+
label: 'Compact',
|
|
15518
|
+
value: 'compact'
|
|
15519
|
+
}, {
|
|
15520
|
+
label: 'Comfortable',
|
|
15521
|
+
value: 'comfortable'
|
|
15522
|
+
}, {
|
|
15523
|
+
label: 'Spacious',
|
|
15524
|
+
value: 'spacious'
|
|
15525
|
+
}]
|
|
15526
|
+
}
|
|
15527
|
+
}), classValidator.IsOptional(), classValidator.IsIn(['compact', 'comfortable', 'spacious']), __metadata("design:type", String)], CollapsibleLayoutModel.prototype, "contentSpacing", void 0);
|
|
15528
|
+
CollapsibleLayoutModel = __decorate([schema.Schema('CollapsibleLayout', '1.0.0')], CollapsibleLayoutModel);
|
|
15529
|
+
var CollapsibleLayoutModel$1 = CollapsibleLayoutModel;
|
|
15530
|
+
|
|
15531
|
+
/**
|
|
15532
|
+
* TypeScript type definitions for CollapsibleLayout component
|
|
15533
|
+
*
|
|
15534
|
+
* Provides TypeScript interfaces that extend the schema model with React-specific types
|
|
15535
|
+
* and component-level functionality for the CollapsibleLayout component.
|
|
15536
|
+
*
|
|
15537
|
+
* Copyright (c) 2025 QwickApps.com. All rights reserved.
|
|
15538
|
+
*/
|
|
15539
|
+
/**
|
|
15540
|
+
* Type guard to check if a component has CollapsibleLayout props
|
|
15541
|
+
*/
|
|
15542
|
+
function isCollapsibleLayoutProps(props) {
|
|
15543
|
+
return props && typeof props === 'object' && ('collapsed' in props || 'defaultCollapsed' in props);
|
|
15544
|
+
}
|
|
15545
|
+
/**
|
|
15546
|
+
* Default props for CollapsibleLayout component
|
|
15547
|
+
*/
|
|
15548
|
+
const defaultCollapsibleLayoutProps = {
|
|
15549
|
+
// Note: collapsed is intentionally omitted so components can be uncontrolled
|
|
15550
|
+
defaultCollapsed: false,
|
|
15551
|
+
triggerArea: 'both',
|
|
15552
|
+
animationStyle: 'slide',
|
|
15553
|
+
persistState: false,
|
|
15554
|
+
showDivider: true,
|
|
15555
|
+
variant: 'default',
|
|
15556
|
+
headerSpacing: 'comfortable',
|
|
15557
|
+
contentSpacing: 'comfortable',
|
|
15558
|
+
animationDuration: 300,
|
|
15559
|
+
disableAnimations: false,
|
|
15560
|
+
toggleAriaLabel: 'Toggle content visibility'
|
|
15561
|
+
};
|
|
15562
|
+
const animationConfigs = {
|
|
15563
|
+
fade: {
|
|
15564
|
+
duration: 300,
|
|
15565
|
+
easing: 'cubic-bezier(0.4, 0, 0.2, 1)',
|
|
15566
|
+
opacity: [0, 1]
|
|
15567
|
+
},
|
|
15568
|
+
slide: {
|
|
15569
|
+
duration: 300,
|
|
15570
|
+
easing: 'cubic-bezier(0.4, 0, 0.2, 1)',
|
|
15571
|
+
transform: 'translateY(-10px)'
|
|
15572
|
+
},
|
|
15573
|
+
scale: {
|
|
15574
|
+
duration: 200,
|
|
15575
|
+
easing: 'cubic-bezier(0.34, 1.56, 0.64, 1)',
|
|
15576
|
+
transform: 'scale(0.95)',
|
|
15577
|
+
opacity: [0, 1]
|
|
15578
|
+
}
|
|
15579
|
+
};
|
|
15580
|
+
const spacingConfigs = {
|
|
15581
|
+
compact: {
|
|
15582
|
+
padding: '8px 12px',
|
|
15583
|
+
gap: '4px'
|
|
15584
|
+
},
|
|
15585
|
+
comfortable: {
|
|
15586
|
+
padding: '16px 20px',
|
|
15587
|
+
gap: '8px'
|
|
15588
|
+
},
|
|
15589
|
+
spacious: {
|
|
15590
|
+
padding: '24px 32px',
|
|
15591
|
+
gap: '16px'
|
|
15592
|
+
}
|
|
15593
|
+
};
|
|
15594
|
+
|
|
15595
|
+
/**
|
|
15596
|
+
* Custom hook for managing collapsible state - simplified approach
|
|
15597
|
+
*/
|
|
15598
|
+
function useCollapsibleState(controlled, collapsedProp, defaultCollapsedProp, onToggleProp, persistState, storageKey) {
|
|
15599
|
+
const id = React.useId();
|
|
15600
|
+
const finalStorageKey = storageKey || `collapsible-${id}`;
|
|
15601
|
+
// For controlled components, use the prop; for uncontrolled, use internal state
|
|
15602
|
+
const [internalCollapsed, setInternalCollapsed] = React.useState(() => {
|
|
15603
|
+
if (controlled) {
|
|
15604
|
+
return collapsedProp ?? false;
|
|
15605
|
+
}
|
|
15606
|
+
// Try localStorage first if persistence is enabled
|
|
15607
|
+
if (persistState && typeof window !== 'undefined') {
|
|
15608
|
+
const stored = localStorage.getItem(finalStorageKey);
|
|
15609
|
+
if (stored !== null) {
|
|
15610
|
+
return JSON.parse(stored);
|
|
15611
|
+
}
|
|
15612
|
+
}
|
|
15613
|
+
return defaultCollapsedProp ?? false;
|
|
15614
|
+
});
|
|
15615
|
+
// Sync with controlled prop changes
|
|
15616
|
+
React.useEffect(() => {
|
|
15617
|
+
if (controlled && collapsedProp !== undefined) {
|
|
15618
|
+
setInternalCollapsed(collapsedProp);
|
|
15619
|
+
}
|
|
15620
|
+
}, [controlled, collapsedProp]);
|
|
15621
|
+
// Persist to localStorage for uncontrolled components
|
|
15622
|
+
React.useEffect(() => {
|
|
15623
|
+
if (!controlled && persistState && typeof window !== 'undefined') {
|
|
15624
|
+
localStorage.setItem(finalStorageKey, JSON.stringify(internalCollapsed));
|
|
15625
|
+
}
|
|
15626
|
+
}, [controlled, internalCollapsed, persistState, finalStorageKey]);
|
|
15627
|
+
const toggle = React.useCallback(() => {
|
|
15628
|
+
const currentState = controlled ? collapsedProp ?? false : internalCollapsed;
|
|
15629
|
+
const newCollapsed = !currentState;
|
|
15630
|
+
// Always update internal state for visual updates
|
|
15631
|
+
setInternalCollapsed(newCollapsed);
|
|
15632
|
+
// Call callback to notify parent
|
|
15633
|
+
onToggleProp?.(newCollapsed);
|
|
15634
|
+
}, [controlled, collapsedProp, internalCollapsed, onToggleProp]);
|
|
15635
|
+
const setCollapsed = React.useCallback(collapsed => {
|
|
15636
|
+
setInternalCollapsed(collapsed);
|
|
15637
|
+
onToggleProp?.(collapsed);
|
|
15638
|
+
}, [onToggleProp]);
|
|
15639
|
+
// Return the appropriate state
|
|
15640
|
+
const finalCollapsed = controlled ? collapsedProp ?? false : internalCollapsed;
|
|
15641
|
+
return {
|
|
15642
|
+
collapsed: finalCollapsed,
|
|
15643
|
+
toggle,
|
|
15644
|
+
setCollapsed,
|
|
15645
|
+
isControlled: controlled
|
|
15646
|
+
};
|
|
15647
|
+
}
|
|
15648
|
+
/**
|
|
15649
|
+
* Core CollapsibleLayout View component
|
|
15650
|
+
*/
|
|
15651
|
+
function CollapsibleLayoutView({
|
|
15652
|
+
// State props
|
|
15653
|
+
collapsed: collapsedProp,
|
|
15654
|
+
defaultCollapsed = false,
|
|
15655
|
+
onToggle,
|
|
15656
|
+
// Content props
|
|
15657
|
+
title,
|
|
15658
|
+
subtitle,
|
|
15659
|
+
leadIcon,
|
|
15660
|
+
headerActions,
|
|
15661
|
+
collapsedView,
|
|
15662
|
+
children,
|
|
15663
|
+
footerView,
|
|
15664
|
+
// Behavior props
|
|
15665
|
+
triggerArea = 'both',
|
|
15666
|
+
animationStyle = 'slide',
|
|
15667
|
+
persistState = false,
|
|
15668
|
+
storageKey,
|
|
15669
|
+
animationDuration = 300,
|
|
15670
|
+
disableAnimations = false,
|
|
15671
|
+
// Icons
|
|
15672
|
+
collapsedIcon,
|
|
15673
|
+
expandedIcon,
|
|
15674
|
+
// Layout props
|
|
15675
|
+
showDivider = true,
|
|
15676
|
+
variant = 'default',
|
|
15677
|
+
headerSpacing = 'comfortable',
|
|
15678
|
+
contentSpacing = 'comfortable',
|
|
15679
|
+
// Accessibility
|
|
15680
|
+
toggleAriaLabel = 'Toggle content visibility',
|
|
15681
|
+
'aria-describedby': ariaDescribedBy,
|
|
15682
|
+
contentAriaProps = {},
|
|
15683
|
+
// CSS classes
|
|
15684
|
+
containerClassName,
|
|
15685
|
+
headerClassName,
|
|
15686
|
+
contentClassName,
|
|
15687
|
+
footerClassName,
|
|
15688
|
+
...restProps
|
|
15689
|
+
}) {
|
|
15690
|
+
const theme = material.useTheme();
|
|
15691
|
+
const {
|
|
15692
|
+
styleProps,
|
|
15693
|
+
htmlProps,
|
|
15694
|
+
restProps: otherProps
|
|
15695
|
+
} = useBaseProps(restProps);
|
|
15696
|
+
// Mark as QwickApp component
|
|
15697
|
+
CollapsibleLayoutView[QWICKAPP_COMPONENT] = true;
|
|
15698
|
+
// Determine controlled vs uncontrolled usage
|
|
15699
|
+
const controlled = collapsedProp !== undefined;
|
|
15700
|
+
// State management
|
|
15701
|
+
const {
|
|
15702
|
+
collapsed,
|
|
15703
|
+
toggle,
|
|
15704
|
+
setCollapsed
|
|
15705
|
+
} = useCollapsibleState(controlled, collapsedProp, defaultCollapsed, onToggle, persistState, storageKey);
|
|
15706
|
+
// Get spacing configurations
|
|
15707
|
+
const headerSpacingConfig = spacingConfigs[headerSpacing];
|
|
15708
|
+
const contentSpacingConfig = spacingConfigs[contentSpacing];
|
|
15709
|
+
// Get animation configuration
|
|
15710
|
+
const animationConfig = animationConfigs[animationStyle];
|
|
15711
|
+
// Generate unique IDs for accessibility
|
|
15712
|
+
const headerId = React.useId();
|
|
15713
|
+
const contentId = React.useId();
|
|
15714
|
+
// Handle click events
|
|
15715
|
+
const handleHeaderClick = React.useCallback(event => {
|
|
15716
|
+
if (triggerArea === 'header' || triggerArea === 'both') {
|
|
15717
|
+
event.preventDefault();
|
|
15718
|
+
toggle();
|
|
15719
|
+
}
|
|
15720
|
+
}, [triggerArea, toggle]);
|
|
15721
|
+
const handleButtonClick = React.useCallback(event => {
|
|
15722
|
+
event.stopPropagation();
|
|
15723
|
+
toggle();
|
|
15724
|
+
}, [toggle]);
|
|
15725
|
+
// Render icons
|
|
15726
|
+
const renderIcon = React.useCallback((icon, defaultIcon) => {
|
|
15727
|
+
if (/*#__PURE__*/React.isValidElement(icon)) {
|
|
15728
|
+
return icon;
|
|
15729
|
+
}
|
|
15730
|
+
if (typeof icon === 'string') {
|
|
15731
|
+
return jsxRuntime.jsx(Html, {
|
|
15732
|
+
children: icon
|
|
15733
|
+
});
|
|
15734
|
+
}
|
|
15735
|
+
return defaultIcon;
|
|
15736
|
+
}, []);
|
|
15737
|
+
const toggleIcon = renderIcon(collapsed ? collapsedIcon : expandedIcon, collapsed ? jsxRuntime.jsx(iconsMaterial.ExpandMore, {}) : jsxRuntime.jsx(iconsMaterial.ExpandLess, {}));
|
|
15738
|
+
// Container styles based on variant
|
|
15739
|
+
const containerSx = React.useMemo(() => {
|
|
15740
|
+
const baseSx = {
|
|
15741
|
+
width: '100%',
|
|
15742
|
+
position: 'relative',
|
|
15743
|
+
...styleProps.sx
|
|
15744
|
+
};
|
|
15745
|
+
switch (variant) {
|
|
15746
|
+
case 'outlined':
|
|
15747
|
+
return {
|
|
15748
|
+
...baseSx,
|
|
15749
|
+
border: `1px solid ${theme.palette.divider}`,
|
|
15750
|
+
borderRadius: 1,
|
|
15751
|
+
backgroundColor: 'var(--theme-surface)'
|
|
15752
|
+
};
|
|
15753
|
+
case 'elevated':
|
|
15754
|
+
return {
|
|
15755
|
+
...baseSx,
|
|
15756
|
+
boxShadow: theme.shadows[2],
|
|
15757
|
+
borderRadius: 1,
|
|
15758
|
+
backgroundColor: theme.palette.background.paper
|
|
15759
|
+
};
|
|
15760
|
+
case 'filled':
|
|
15761
|
+
return {
|
|
15762
|
+
...baseSx,
|
|
15763
|
+
backgroundColor: 'var(--theme-surface-variant)',
|
|
15764
|
+
borderRadius: 1
|
|
15765
|
+
};
|
|
15766
|
+
default:
|
|
15767
|
+
return baseSx;
|
|
15768
|
+
}
|
|
15769
|
+
}, [variant, theme, styleProps.sx]);
|
|
15770
|
+
// Header styles
|
|
15771
|
+
const headerSx = React.useMemo(() => ({
|
|
15772
|
+
...headerSpacingConfig,
|
|
15773
|
+
cursor: triggerArea === 'header' || triggerArea === 'both' ? 'pointer' : 'default',
|
|
15774
|
+
userSelect: 'none',
|
|
15775
|
+
display: 'flex',
|
|
15776
|
+
alignItems: 'center',
|
|
15777
|
+
justifyContent: 'space-between',
|
|
15778
|
+
'&:hover': triggerArea === 'header' || triggerArea === 'both' ? {
|
|
15779
|
+
backgroundColor: 'rgba(0, 0, 0, 0.04)'
|
|
15780
|
+
} : {}
|
|
15781
|
+
}), [headerSpacingConfig, triggerArea]);
|
|
15782
|
+
// Content styles
|
|
15783
|
+
const contentSx = React.useMemo(() => ({
|
|
15784
|
+
...contentSpacingConfig
|
|
15785
|
+
}), [contentSpacingConfig]);
|
|
15786
|
+
// Animation props for Collapse component
|
|
15787
|
+
const collapseProps = React.useMemo(() => {
|
|
15788
|
+
if (disableAnimations) {
|
|
15789
|
+
return {
|
|
15790
|
+
timeout: 0
|
|
15791
|
+
};
|
|
15792
|
+
}
|
|
15793
|
+
const baseProps = {
|
|
15794
|
+
timeout: animationDuration
|
|
15795
|
+
};
|
|
15796
|
+
switch (animationStyle) {
|
|
15797
|
+
case 'fade':
|
|
15798
|
+
return {
|
|
15799
|
+
...baseProps,
|
|
15800
|
+
sx: {
|
|
15801
|
+
'& .MuiCollapse-wrapper': {
|
|
15802
|
+
opacity: collapsed ? 0 : 1,
|
|
15803
|
+
transition: `opacity ${animationDuration}ms ${animationConfig.easing}`
|
|
15804
|
+
}
|
|
15805
|
+
}
|
|
15806
|
+
};
|
|
15807
|
+
case 'scale':
|
|
15808
|
+
return {
|
|
15809
|
+
...baseProps,
|
|
15810
|
+
sx: {
|
|
15811
|
+
'& .MuiCollapse-wrapper': {
|
|
15812
|
+
transform: collapsed ? 'scale(0.95)' : 'scale(1)',
|
|
15813
|
+
opacity: collapsed ? 0 : 1,
|
|
15814
|
+
transition: `all ${animationDuration}ms ${animationConfig.easing}`
|
|
15815
|
+
}
|
|
15816
|
+
}
|
|
15817
|
+
};
|
|
15818
|
+
default:
|
|
15819
|
+
// slide
|
|
15820
|
+
return baseProps;
|
|
15821
|
+
}
|
|
15822
|
+
}, [disableAnimations, animationDuration, animationStyle, animationConfig, collapsed]);
|
|
15823
|
+
// Render content based on type
|
|
15824
|
+
const renderContent = React.useCallback(content => {
|
|
15825
|
+
if (!content) return null;
|
|
15826
|
+
if (typeof content === 'string') {
|
|
15827
|
+
return jsxRuntime.jsx(Html, {
|
|
15828
|
+
children: content
|
|
15829
|
+
});
|
|
15830
|
+
}
|
|
15831
|
+
return content;
|
|
15832
|
+
}, []);
|
|
15833
|
+
// Container content that will be wrapped
|
|
15834
|
+
const containerContent = jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
15835
|
+
children: [(title || subtitle || leadIcon || headerActions || triggerArea === 'button' || triggerArea === 'both') && jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
15836
|
+
children: [jsxRuntime.jsxs(material.Box, {
|
|
15837
|
+
id: headerId,
|
|
15838
|
+
className: headerClassName,
|
|
15839
|
+
sx: headerSx,
|
|
15840
|
+
onClick: handleHeaderClick,
|
|
15841
|
+
role: triggerArea === 'header' || triggerArea === 'both' ? 'button' : undefined,
|
|
15842
|
+
tabIndex: triggerArea === 'header' || triggerArea === 'both' ? 0 : undefined,
|
|
15843
|
+
"aria-expanded": !collapsed,
|
|
15844
|
+
"aria-controls": contentId,
|
|
15845
|
+
"aria-describedby": ariaDescribedBy,
|
|
15846
|
+
onKeyDown: e => {
|
|
15847
|
+
if ((triggerArea === 'header' || triggerArea === 'both') && (e.key === 'Enter' || e.key === ' ')) {
|
|
15848
|
+
e.preventDefault();
|
|
15849
|
+
toggle();
|
|
15850
|
+
}
|
|
15851
|
+
},
|
|
15852
|
+
children: [jsxRuntime.jsxs(material.Stack, {
|
|
15853
|
+
direction: "row",
|
|
15854
|
+
spacing: 2,
|
|
15855
|
+
alignItems: "center",
|
|
15856
|
+
sx: {
|
|
15857
|
+
minWidth: 0,
|
|
15858
|
+
flex: 1
|
|
15859
|
+
},
|
|
15860
|
+
children: [leadIcon && jsxRuntime.jsx(material.Box, {
|
|
15861
|
+
sx: {
|
|
15862
|
+
flexShrink: 0
|
|
15863
|
+
},
|
|
15864
|
+
children: renderContent(leadIcon)
|
|
15865
|
+
}), (title || subtitle) && jsxRuntime.jsxs(material.Box, {
|
|
15866
|
+
sx: {
|
|
15867
|
+
minWidth: 0,
|
|
15868
|
+
flex: 1
|
|
15869
|
+
},
|
|
15870
|
+
children: [title && jsxRuntime.jsx(material.Typography, {
|
|
15871
|
+
variant: "h6",
|
|
15872
|
+
component: "h3",
|
|
15873
|
+
sx: {
|
|
15874
|
+
fontWeight: 600,
|
|
15875
|
+
lineHeight: 1.2,
|
|
15876
|
+
...(subtitle && {
|
|
15877
|
+
mb: 0.5
|
|
15878
|
+
})
|
|
15879
|
+
},
|
|
15880
|
+
children: title
|
|
15881
|
+
}), subtitle && jsxRuntime.jsx(material.Typography, {
|
|
15882
|
+
variant: "body2",
|
|
15883
|
+
color: "text.secondary",
|
|
15884
|
+
sx: {
|
|
15885
|
+
lineHeight: 1.3
|
|
15886
|
+
},
|
|
15887
|
+
children: subtitle
|
|
15888
|
+
})]
|
|
15889
|
+
})]
|
|
15890
|
+
}), jsxRuntime.jsxs(material.Stack, {
|
|
15891
|
+
direction: "row",
|
|
15892
|
+
spacing: 1,
|
|
15893
|
+
alignItems: "center",
|
|
15894
|
+
sx: {
|
|
15895
|
+
flexShrink: 0
|
|
15896
|
+
},
|
|
15897
|
+
children: [headerActions && jsxRuntime.jsx(material.Box, {
|
|
15898
|
+
children: renderContent(headerActions)
|
|
15899
|
+
}), jsxRuntime.jsx(material.IconButton, {
|
|
15900
|
+
onClick: handleButtonClick,
|
|
15901
|
+
size: "small",
|
|
15902
|
+
"aria-label": toggleAriaLabel,
|
|
15903
|
+
"aria-expanded": !collapsed,
|
|
15904
|
+
"aria-controls": contentId,
|
|
15905
|
+
children: toggleIcon
|
|
15906
|
+
})]
|
|
15907
|
+
})]
|
|
15908
|
+
}), showDivider && jsxRuntime.jsx(material.Divider, {})]
|
|
15909
|
+
}), collapsed && collapsedView && jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
15910
|
+
children: [jsxRuntime.jsx(material.Box, {
|
|
15911
|
+
className: contentClassName,
|
|
15912
|
+
sx: contentSx,
|
|
15913
|
+
children: renderContent(collapsedView)
|
|
15914
|
+
}), showDivider && footerView && jsxRuntime.jsx(material.Divider, {})]
|
|
15915
|
+
}), jsxRuntime.jsxs(material.Collapse, {
|
|
15916
|
+
in: !collapsed,
|
|
15917
|
+
...collapseProps,
|
|
15918
|
+
children: [jsxRuntime.jsx(material.Box, {
|
|
15919
|
+
id: contentId,
|
|
15920
|
+
className: contentClassName,
|
|
15921
|
+
sx: contentSx,
|
|
15922
|
+
role: "region",
|
|
15923
|
+
"aria-labelledby": title ? headerId : undefined,
|
|
15924
|
+
...contentAriaProps,
|
|
15925
|
+
children: renderContent(children)
|
|
15926
|
+
}), showDivider && footerView && jsxRuntime.jsx(material.Divider, {})]
|
|
15927
|
+
}), footerView && jsxRuntime.jsx(material.Box, {
|
|
15928
|
+
className: footerClassName,
|
|
15929
|
+
sx: contentSx,
|
|
15930
|
+
children: renderContent(footerView)
|
|
15931
|
+
})]
|
|
15932
|
+
});
|
|
15933
|
+
// Return appropriate container based on variant
|
|
15934
|
+
if (variant === 'outlined') {
|
|
15935
|
+
return jsxRuntime.jsx(material.Paper, {
|
|
15936
|
+
variant: "outlined",
|
|
15937
|
+
elevation: 0,
|
|
15938
|
+
...htmlProps,
|
|
15939
|
+
...otherProps,
|
|
15940
|
+
className: containerClassName,
|
|
15941
|
+
sx: containerSx,
|
|
15942
|
+
children: containerContent
|
|
15943
|
+
});
|
|
15944
|
+
}
|
|
15945
|
+
if (variant === 'elevated') {
|
|
15946
|
+
return jsxRuntime.jsx(material.Paper, {
|
|
15947
|
+
elevation: 2,
|
|
15948
|
+
...htmlProps,
|
|
15949
|
+
...otherProps,
|
|
15950
|
+
className: containerClassName,
|
|
15951
|
+
sx: containerSx,
|
|
15952
|
+
children: containerContent
|
|
15953
|
+
});
|
|
15954
|
+
}
|
|
15955
|
+
// Default variant (default, filled)
|
|
15956
|
+
return jsxRuntime.jsx(material.Box, {
|
|
15957
|
+
...htmlProps,
|
|
15958
|
+
...otherProps,
|
|
15959
|
+
className: containerClassName,
|
|
15960
|
+
sx: containerSx,
|
|
15961
|
+
children: containerContent
|
|
15962
|
+
});
|
|
15963
|
+
}
|
|
15964
|
+
/**
|
|
15965
|
+
* Main CollapsibleLayout component with data binding support
|
|
15966
|
+
*/
|
|
15967
|
+
function CollapsibleLayout(props) {
|
|
15968
|
+
const {
|
|
15969
|
+
dataSource,
|
|
15970
|
+
bindingOptions,
|
|
15971
|
+
...restProps
|
|
15972
|
+
} = props;
|
|
15973
|
+
// If no dataSource, use traditional props
|
|
15974
|
+
if (!dataSource) {
|
|
15975
|
+
return jsxRuntime.jsx(CollapsibleLayoutView, {
|
|
15976
|
+
...restProps
|
|
15977
|
+
});
|
|
15978
|
+
}
|
|
15979
|
+
// Use data binding
|
|
15980
|
+
const {
|
|
15981
|
+
dataSource: _source,
|
|
15982
|
+
loading,
|
|
15983
|
+
error,
|
|
15984
|
+
cached,
|
|
15985
|
+
...collapsibleProps
|
|
15986
|
+
} = useDataBinding(dataSource, restProps, CollapsibleLayoutModel$1.getSchema(), {
|
|
15987
|
+
cache: true,
|
|
15988
|
+
cacheTTL: 300000,
|
|
15989
|
+
strict: false,
|
|
15990
|
+
...bindingOptions
|
|
15991
|
+
});
|
|
15992
|
+
// Show loading state
|
|
15993
|
+
if (loading) {
|
|
15994
|
+
return jsxRuntime.jsx(CollapsibleLayoutView, {
|
|
15995
|
+
...restProps,
|
|
15996
|
+
title: "Loading...",
|
|
15997
|
+
variant: "default",
|
|
15998
|
+
headerSpacing: "comfortable",
|
|
15999
|
+
contentSpacing: "comfortable"
|
|
16000
|
+
});
|
|
16001
|
+
}
|
|
16002
|
+
if (error) {
|
|
16003
|
+
console.error('Error loading collapsible layout:', error);
|
|
16004
|
+
{
|
|
16005
|
+
return jsxRuntime.jsx(CollapsibleLayoutView, {
|
|
16006
|
+
...restProps,
|
|
16007
|
+
title: "Error Loading Layout",
|
|
16008
|
+
subtitle: error.message,
|
|
16009
|
+
variant: "outlined",
|
|
16010
|
+
headerSpacing: "comfortable",
|
|
16011
|
+
contentSpacing: "comfortable"
|
|
16012
|
+
});
|
|
16013
|
+
}
|
|
16014
|
+
}
|
|
16015
|
+
return jsxRuntime.jsx(CollapsibleLayoutView, {
|
|
16016
|
+
...collapsibleProps
|
|
16017
|
+
});
|
|
16018
|
+
}
|
|
16019
|
+
// Set default props
|
|
16020
|
+
CollapsibleLayout.defaultProps = defaultCollapsibleLayoutProps;
|
|
16021
|
+
|
|
15339
16022
|
/**
|
|
15340
16023
|
* FeatureCard Schema - Schema definition for FeatureCard component
|
|
15341
16024
|
*
|
|
@@ -18728,7 +19411,7 @@ function FormBlockView({
|
|
|
18728
19411
|
title,
|
|
18729
19412
|
description,
|
|
18730
19413
|
coverImage,
|
|
18731
|
-
form,
|
|
19414
|
+
children: form,
|
|
18732
19415
|
footer,
|
|
18733
19416
|
status,
|
|
18734
19417
|
message,
|
|
@@ -19686,8 +20369,195 @@ function SelectInputField(props) {
|
|
|
19686
20369
|
strict: false,
|
|
19687
20370
|
...bindingOptions
|
|
19688
20371
|
});
|
|
19689
|
-
// Show loading state
|
|
19690
|
-
if (loading) {
|
|
20372
|
+
// Show loading state
|
|
20373
|
+
if (loading) {
|
|
20374
|
+
return jsxRuntime.jsxs(material.Paper, {
|
|
20375
|
+
variant: "outlined",
|
|
20376
|
+
sx: {
|
|
20377
|
+
p: 2,
|
|
20378
|
+
textAlign: 'center'
|
|
20379
|
+
},
|
|
20380
|
+
children: [jsxRuntime.jsx(material.Typography, {
|
|
20381
|
+
variant: "body2",
|
|
20382
|
+
children: "Loading SelectInputField..."
|
|
20383
|
+
}), jsxRuntime.jsx(material.Typography, {
|
|
20384
|
+
variant: "caption",
|
|
20385
|
+
color: "text.secondary",
|
|
20386
|
+
children: "Loading select field configuration from data source..."
|
|
20387
|
+
})]
|
|
20388
|
+
});
|
|
20389
|
+
}
|
|
20390
|
+
if (error) {
|
|
20391
|
+
console.error('Error loading select input field:', error);
|
|
20392
|
+
{
|
|
20393
|
+
return jsxRuntime.jsx(material.Paper, {
|
|
20394
|
+
variant: "outlined",
|
|
20395
|
+
sx: {
|
|
20396
|
+
p: 2,
|
|
20397
|
+
textAlign: 'center',
|
|
20398
|
+
borderColor: 'error.main'
|
|
20399
|
+
},
|
|
20400
|
+
children: jsxRuntime.jsxs(material.Typography, {
|
|
20401
|
+
variant: "body2",
|
|
20402
|
+
color: "error",
|
|
20403
|
+
children: ["Error loading select field: ", error.message]
|
|
20404
|
+
})
|
|
20405
|
+
});
|
|
20406
|
+
}
|
|
20407
|
+
}
|
|
20408
|
+
return jsxRuntime.jsx(SelectInputFieldView, {
|
|
20409
|
+
...selectInputFieldProps
|
|
20410
|
+
});
|
|
20411
|
+
}
|
|
20412
|
+
// Mark as QwickApp component
|
|
20413
|
+
SelectInputField[QWICKAPP_COMPONENT] = true;
|
|
20414
|
+
|
|
20415
|
+
/**
|
|
20416
|
+
* SwitchInputField Schema - Data model for switch input field component
|
|
20417
|
+
*
|
|
20418
|
+
* Copyright (c) 2025 QwickApps.com. All rights reserved.
|
|
20419
|
+
*/
|
|
20420
|
+
let SwitchInputFieldModel = class SwitchInputFieldModel extends schema.Model {};
|
|
20421
|
+
__decorate([schema.Field(), schema.Editor({
|
|
20422
|
+
field_type: schema.FieldType.TEXT,
|
|
20423
|
+
label: 'Label',
|
|
20424
|
+
description: 'The label text for the switch'
|
|
20425
|
+
}), classValidator.IsOptional(), classValidator.IsString(), __metadata("design:type", String)], SwitchInputFieldModel.prototype, "label", void 0);
|
|
20426
|
+
__decorate([schema.Field({
|
|
20427
|
+
defaultValue: false
|
|
20428
|
+
}), schema.Editor({
|
|
20429
|
+
field_type: schema.FieldType.BOOLEAN,
|
|
20430
|
+
label: 'Checked',
|
|
20431
|
+
description: 'Whether the switch is checked'
|
|
20432
|
+
}), classValidator.IsOptional(), classValidator.IsBoolean(), __metadata("design:type", Boolean)], SwitchInputFieldModel.prototype, "checked", void 0);
|
|
20433
|
+
__decorate([schema.Field({
|
|
20434
|
+
defaultValue: false
|
|
20435
|
+
}), schema.Editor({
|
|
20436
|
+
field_type: schema.FieldType.BOOLEAN,
|
|
20437
|
+
label: 'Required',
|
|
20438
|
+
description: 'Whether the field is required'
|
|
20439
|
+
}), classValidator.IsOptional(), classValidator.IsBoolean(), __metadata("design:type", Boolean)], SwitchInputFieldModel.prototype, "required", void 0);
|
|
20440
|
+
__decorate([schema.Field({
|
|
20441
|
+
defaultValue: false
|
|
20442
|
+
}), schema.Editor({
|
|
20443
|
+
field_type: schema.FieldType.BOOLEAN,
|
|
20444
|
+
label: 'Disabled',
|
|
20445
|
+
description: 'Whether the field is disabled'
|
|
20446
|
+
}), classValidator.IsOptional(), classValidator.IsBoolean(), __metadata("design:type", Boolean)], SwitchInputFieldModel.prototype, "disabled", void 0);
|
|
20447
|
+
__decorate([schema.Field(), schema.Editor({
|
|
20448
|
+
field_type: schema.FieldType.TEXT,
|
|
20449
|
+
label: 'Error',
|
|
20450
|
+
description: 'Error message to display'
|
|
20451
|
+
}), classValidator.IsOptional(), classValidator.IsString(), __metadata("design:type", String)], SwitchInputFieldModel.prototype, "error", void 0);
|
|
20452
|
+
__decorate([schema.Field(), schema.Editor({
|
|
20453
|
+
field_type: schema.FieldType.TEXT,
|
|
20454
|
+
label: 'Helper Text',
|
|
20455
|
+
description: 'Helper text to display below the switch'
|
|
20456
|
+
}), classValidator.IsOptional(), classValidator.IsString(), __metadata("design:type", String)], SwitchInputFieldModel.prototype, "helperText", void 0);
|
|
20457
|
+
__decorate([schema.Field({
|
|
20458
|
+
defaultValue: 'medium'
|
|
20459
|
+
}), schema.Editor({
|
|
20460
|
+
field_type: schema.FieldType.SELECT,
|
|
20461
|
+
label: 'Size',
|
|
20462
|
+
description: 'Size of the switch'
|
|
20463
|
+
}), classValidator.IsOptional(), classValidator.IsString(), __metadata("design:type", String)], SwitchInputFieldModel.prototype, "size", void 0);
|
|
20464
|
+
__decorate([schema.Field({
|
|
20465
|
+
defaultValue: 'primary'
|
|
20466
|
+
}), schema.Editor({
|
|
20467
|
+
field_type: schema.FieldType.SELECT,
|
|
20468
|
+
label: 'Color',
|
|
20469
|
+
description: 'Color theme of the switch'
|
|
20470
|
+
}), classValidator.IsOptional(), classValidator.IsString(), __metadata("design:type", String)], SwitchInputFieldModel.prototype, "color", void 0);
|
|
20471
|
+
SwitchInputFieldModel = __decorate([schema.Schema('SwitchInputField', '1.0.0')], SwitchInputFieldModel);
|
|
20472
|
+
var SwitchInputFieldModel$1 = SwitchInputFieldModel;
|
|
20473
|
+
|
|
20474
|
+
// View component - handles the actual rendering
|
|
20475
|
+
function SwitchInputFieldView({
|
|
20476
|
+
label,
|
|
20477
|
+
checked = false,
|
|
20478
|
+
onChange,
|
|
20479
|
+
onFocus,
|
|
20480
|
+
required = false,
|
|
20481
|
+
disabled = false,
|
|
20482
|
+
error,
|
|
20483
|
+
helperText,
|
|
20484
|
+
size = 'medium',
|
|
20485
|
+
color = 'primary',
|
|
20486
|
+
...restProps
|
|
20487
|
+
}) {
|
|
20488
|
+
const {
|
|
20489
|
+
styleProps,
|
|
20490
|
+
htmlProps
|
|
20491
|
+
} = useBaseProps(restProps);
|
|
20492
|
+
const handleChange = event => {
|
|
20493
|
+
if (onChange) {
|
|
20494
|
+
onChange(event.target.checked);
|
|
20495
|
+
}
|
|
20496
|
+
};
|
|
20497
|
+
return jsxRuntime.jsxs(material.FormControl, {
|
|
20498
|
+
...htmlProps,
|
|
20499
|
+
...styleProps,
|
|
20500
|
+
error: !!error,
|
|
20501
|
+
required: required,
|
|
20502
|
+
disabled: disabled,
|
|
20503
|
+
sx: {
|
|
20504
|
+
display: 'block',
|
|
20505
|
+
...styleProps.sx
|
|
20506
|
+
},
|
|
20507
|
+
children: [jsxRuntime.jsx(material.FormControlLabel, {
|
|
20508
|
+
control: jsxRuntime.jsx(material.Switch, {
|
|
20509
|
+
checked: checked,
|
|
20510
|
+
onChange: handleChange,
|
|
20511
|
+
onFocus: onFocus,
|
|
20512
|
+
size: size,
|
|
20513
|
+
color: color,
|
|
20514
|
+
disabled: disabled
|
|
20515
|
+
}),
|
|
20516
|
+
label: label,
|
|
20517
|
+
disabled: disabled
|
|
20518
|
+
}), (error || helperText) && jsxRuntime.jsx(material.FormHelperText, {
|
|
20519
|
+
children: error || helperText
|
|
20520
|
+
})]
|
|
20521
|
+
});
|
|
20522
|
+
}
|
|
20523
|
+
/**
|
|
20524
|
+
* SwitchInputField component with data binding support
|
|
20525
|
+
* Supports both traditional props and dataSource-driven rendering
|
|
20526
|
+
*/
|
|
20527
|
+
function SwitchInputField(props) {
|
|
20528
|
+
const {
|
|
20529
|
+
dataSource,
|
|
20530
|
+
bindingOptions,
|
|
20531
|
+
...restProps
|
|
20532
|
+
} = props;
|
|
20533
|
+
// If no dataSource, use traditional props
|
|
20534
|
+
if (!dataSource) {
|
|
20535
|
+
return jsxRuntime.jsx(SwitchInputFieldView, {
|
|
20536
|
+
...restProps
|
|
20537
|
+
});
|
|
20538
|
+
}
|
|
20539
|
+
// Use data binding
|
|
20540
|
+
const bindingResult = useDataBinding(dataSource, restProps, SwitchInputFieldModel$1.getSchema(), {
|
|
20541
|
+
cache: true,
|
|
20542
|
+
cacheTTL: 300000,
|
|
20543
|
+
strict: false,
|
|
20544
|
+
...bindingOptions
|
|
20545
|
+
});
|
|
20546
|
+
// Check if we're still loading data using the metadata properties
|
|
20547
|
+
const bindingLoading = bindingResult.$loading;
|
|
20548
|
+
// Extract all the actual switch properties (excluding metadata)
|
|
20549
|
+
const {
|
|
20550
|
+
dataSource: _source,
|
|
20551
|
+
$loading,
|
|
20552
|
+
$error,
|
|
20553
|
+
$dataSource,
|
|
20554
|
+
$cached,
|
|
20555
|
+
cached,
|
|
20556
|
+
...switchInputFieldProps
|
|
20557
|
+
} = bindingResult;
|
|
20558
|
+
const error = bindingResult.$error;
|
|
20559
|
+
// Show loading state while fetching data
|
|
20560
|
+
if (bindingLoading) {
|
|
19691
20561
|
return jsxRuntime.jsxs(material.Paper, {
|
|
19692
20562
|
variant: "outlined",
|
|
19693
20563
|
sx: {
|
|
@@ -19696,16 +20566,16 @@ function SelectInputField(props) {
|
|
|
19696
20566
|
},
|
|
19697
20567
|
children: [jsxRuntime.jsx(material.Typography, {
|
|
19698
20568
|
variant: "body2",
|
|
19699
|
-
children: "Loading
|
|
20569
|
+
children: "Loading SwitchInputField..."
|
|
19700
20570
|
}), jsxRuntime.jsx(material.Typography, {
|
|
19701
20571
|
variant: "caption",
|
|
19702
20572
|
color: "text.secondary",
|
|
19703
|
-
children: "Loading
|
|
20573
|
+
children: "Loading switch field configuration from data source..."
|
|
19704
20574
|
})]
|
|
19705
20575
|
});
|
|
19706
20576
|
}
|
|
19707
20577
|
if (error) {
|
|
19708
|
-
console.error('Error loading
|
|
20578
|
+
console.error('Error loading switch input field:', error);
|
|
19709
20579
|
{
|
|
19710
20580
|
return jsxRuntime.jsx(material.Paper, {
|
|
19711
20581
|
variant: "outlined",
|
|
@@ -19717,17 +20587,17 @@ function SelectInputField(props) {
|
|
|
19717
20587
|
children: jsxRuntime.jsxs(material.Typography, {
|
|
19718
20588
|
variant: "body2",
|
|
19719
20589
|
color: "error",
|
|
19720
|
-
children: ["Error loading
|
|
20590
|
+
children: ["Error loading switch field: ", error.message]
|
|
19721
20591
|
})
|
|
19722
20592
|
});
|
|
19723
20593
|
}
|
|
19724
20594
|
}
|
|
19725
|
-
return jsxRuntime.jsx(
|
|
19726
|
-
...
|
|
20595
|
+
return jsxRuntime.jsx(SwitchInputFieldView, {
|
|
20596
|
+
...switchInputFieldProps
|
|
19727
20597
|
});
|
|
19728
20598
|
}
|
|
19729
20599
|
// Mark as QwickApp component
|
|
19730
|
-
|
|
20600
|
+
SwitchInputField[QWICKAPP_COMPONENT] = true;
|
|
19731
20601
|
|
|
19732
20602
|
const TextField = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
19733
20603
|
const {
|
|
@@ -20225,7 +21095,7 @@ const FormPage = ({
|
|
|
20225
21095
|
title: title,
|
|
20226
21096
|
description: description,
|
|
20227
21097
|
coverImage: coverImage,
|
|
20228
|
-
|
|
21098
|
+
children: form,
|
|
20229
21099
|
footer: footer,
|
|
20230
21100
|
status: status,
|
|
20231
21101
|
message: message,
|
|
@@ -20581,6 +21451,605 @@ const Scaffold = ({
|
|
|
20581
21451
|
|
|
20582
21452
|
loggers.menu;
|
|
20583
21453
|
|
|
21454
|
+
/**
|
|
21455
|
+
* Generic ErrorBoundary component for catching and handling React errors
|
|
21456
|
+
*
|
|
21457
|
+
* Features:
|
|
21458
|
+
* - Catches JavaScript errors anywhere in child component tree
|
|
21459
|
+
* - Displays fallback UI with retry functionality
|
|
21460
|
+
* - Shows error details in development mode
|
|
21461
|
+
* - Customizable error handling and fallback UI
|
|
21462
|
+
* - Automatic error logging
|
|
21463
|
+
*/
|
|
21464
|
+
class ErrorBoundary extends React.Component {
|
|
21465
|
+
constructor(props) {
|
|
21466
|
+
super(props);
|
|
21467
|
+
this.handleRetry = () => {
|
|
21468
|
+
this.setState({
|
|
21469
|
+
hasError: false,
|
|
21470
|
+
error: null,
|
|
21471
|
+
errorInfo: null
|
|
21472
|
+
});
|
|
21473
|
+
};
|
|
21474
|
+
this.handleRefresh = () => {
|
|
21475
|
+
if (typeof window !== 'undefined') {
|
|
21476
|
+
window.location.reload();
|
|
21477
|
+
}
|
|
21478
|
+
};
|
|
21479
|
+
this.state = {
|
|
21480
|
+
hasError: false,
|
|
21481
|
+
error: null,
|
|
21482
|
+
errorInfo: null
|
|
21483
|
+
};
|
|
21484
|
+
}
|
|
21485
|
+
static getDerivedStateFromError(error) {
|
|
21486
|
+
// Update state so the next render will show the fallback UI
|
|
21487
|
+
return {
|
|
21488
|
+
hasError: true,
|
|
21489
|
+
error,
|
|
21490
|
+
errorInfo: null
|
|
21491
|
+
};
|
|
21492
|
+
}
|
|
21493
|
+
componentDidCatch(error, errorInfo) {
|
|
21494
|
+
// Log error details
|
|
21495
|
+
this.setState({
|
|
21496
|
+
error,
|
|
21497
|
+
errorInfo
|
|
21498
|
+
});
|
|
21499
|
+
// Log to console for debugging
|
|
21500
|
+
console.error('ErrorBoundary caught an error:', error, errorInfo);
|
|
21501
|
+
// Custom error handler
|
|
21502
|
+
if (this.props.onError) {
|
|
21503
|
+
this.props.onError(error, errorInfo);
|
|
21504
|
+
}
|
|
21505
|
+
// Send error to logging service if available
|
|
21506
|
+
if (typeof window !== 'undefined') {
|
|
21507
|
+
// @ts-ignore - Global error logging service
|
|
21508
|
+
if (window.qwickapps?.logError) {
|
|
21509
|
+
window.qwickapps.logError(error, errorInfo);
|
|
21510
|
+
}
|
|
21511
|
+
}
|
|
21512
|
+
}
|
|
21513
|
+
render() {
|
|
21514
|
+
if (this.state.hasError) {
|
|
21515
|
+
// Custom fallback UI
|
|
21516
|
+
if (this.props.fallback) {
|
|
21517
|
+
return this.props.fallback;
|
|
21518
|
+
}
|
|
21519
|
+
// Default error UI
|
|
21520
|
+
return jsxRuntime.jsxs("div", {
|
|
21521
|
+
className: "error-boundary",
|
|
21522
|
+
role: "alert",
|
|
21523
|
+
style: {
|
|
21524
|
+
padding: '2rem',
|
|
21525
|
+
textAlign: 'center',
|
|
21526
|
+
backgroundColor: '#fef2f2',
|
|
21527
|
+
border: '1px solid #fecaca',
|
|
21528
|
+
borderRadius: '8px',
|
|
21529
|
+
margin: '1rem',
|
|
21530
|
+
color: '#991b1b'
|
|
21531
|
+
},
|
|
21532
|
+
children: [jsxRuntime.jsxs("div", {
|
|
21533
|
+
style: {
|
|
21534
|
+
marginBottom: '1.5rem'
|
|
21535
|
+
},
|
|
21536
|
+
children: [jsxRuntime.jsx("h2", {
|
|
21537
|
+
style: {
|
|
21538
|
+
fontSize: '1.5rem',
|
|
21539
|
+
fontWeight: 'bold',
|
|
21540
|
+
marginBottom: '0.5rem',
|
|
21541
|
+
color: '#991b1b'
|
|
21542
|
+
},
|
|
21543
|
+
children: "Something went wrong"
|
|
21544
|
+
}), jsxRuntime.jsx("p", {
|
|
21545
|
+
style: {
|
|
21546
|
+
color: '#7f1d1d',
|
|
21547
|
+
marginBottom: '1rem'
|
|
21548
|
+
},
|
|
21549
|
+
children: "An unexpected error occurred in the application. Please try again or refresh the page."
|
|
21550
|
+
})]
|
|
21551
|
+
}), jsxRuntime.jsxs("div", {
|
|
21552
|
+
style: {
|
|
21553
|
+
display: 'flex',
|
|
21554
|
+
gap: '0.75rem',
|
|
21555
|
+
justifyContent: 'center',
|
|
21556
|
+
marginBottom: '1rem'
|
|
21557
|
+
},
|
|
21558
|
+
children: [jsxRuntime.jsx(Button, {
|
|
21559
|
+
variant: "contained",
|
|
21560
|
+
onClick: this.handleRetry,
|
|
21561
|
+
style: {
|
|
21562
|
+
backgroundColor: '#dc2626',
|
|
21563
|
+
color: 'white'
|
|
21564
|
+
},
|
|
21565
|
+
children: "Try Again"
|
|
21566
|
+
}), jsxRuntime.jsx(Button, {
|
|
21567
|
+
variant: "outlined",
|
|
21568
|
+
onClick: this.handleRefresh,
|
|
21569
|
+
style: {
|
|
21570
|
+
borderColor: '#dc2626',
|
|
21571
|
+
color: '#dc2626'
|
|
21572
|
+
},
|
|
21573
|
+
children: "Refresh Page"
|
|
21574
|
+
})]
|
|
21575
|
+
}), this.state.error && jsxRuntime.jsxs("details", {
|
|
21576
|
+
style: {
|
|
21577
|
+
textAlign: 'left',
|
|
21578
|
+
marginTop: '1rem',
|
|
21579
|
+
padding: '1rem',
|
|
21580
|
+
backgroundColor: '#f9fafb',
|
|
21581
|
+
border: '1px solid #d1d5db',
|
|
21582
|
+
borderRadius: '6px'
|
|
21583
|
+
},
|
|
21584
|
+
children: [jsxRuntime.jsx("summary", {
|
|
21585
|
+
style: {
|
|
21586
|
+
cursor: 'pointer',
|
|
21587
|
+
fontWeight: 'bold',
|
|
21588
|
+
marginBottom: '0.5rem',
|
|
21589
|
+
color: '#374151'
|
|
21590
|
+
},
|
|
21591
|
+
children: "Error Details (Development Mode)"
|
|
21592
|
+
}), jsxRuntime.jsxs("pre", {
|
|
21593
|
+
style: {
|
|
21594
|
+
fontSize: '0.75rem',
|
|
21595
|
+
color: '#374151',
|
|
21596
|
+
whiteSpace: 'pre-wrap',
|
|
21597
|
+
overflow: 'auto'
|
|
21598
|
+
},
|
|
21599
|
+
children: [this.state.error.toString(), this.state.errorInfo?.componentStack && jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
21600
|
+
children: [jsxRuntime.jsx("br", {}), jsxRuntime.jsx("br", {}), "Component Stack:", this.state.errorInfo.componentStack]
|
|
21601
|
+
})]
|
|
21602
|
+
})]
|
|
21603
|
+
})]
|
|
21604
|
+
});
|
|
21605
|
+
}
|
|
21606
|
+
return this.props.children;
|
|
21607
|
+
}
|
|
21608
|
+
}
|
|
21609
|
+
/**
|
|
21610
|
+
* Higher-order component that wraps a component with ErrorBoundary
|
|
21611
|
+
*/
|
|
21612
|
+
function withErrorBoundary(WrappedComponent, errorBoundaryProps) {
|
|
21613
|
+
const WithErrorBoundaryComponent = props => jsxRuntime.jsx(ErrorBoundary, {
|
|
21614
|
+
...errorBoundaryProps,
|
|
21615
|
+
children: jsxRuntime.jsx(WrappedComponent, {
|
|
21616
|
+
...props
|
|
21617
|
+
})
|
|
21618
|
+
});
|
|
21619
|
+
WithErrorBoundaryComponent.displayName = `withErrorBoundary(${WrappedComponent.displayName || WrappedComponent.name || 'Component'})`;
|
|
21620
|
+
return WithErrorBoundaryComponent;
|
|
21621
|
+
}
|
|
21622
|
+
|
|
21623
|
+
const AccessibilityContext = /*#__PURE__*/React.createContext(null);
|
|
21624
|
+
// Reducer
|
|
21625
|
+
const accessibilityReducer = (state, action) => {
|
|
21626
|
+
switch (action.type) {
|
|
21627
|
+
case 'SET_HIGH_CONTRAST':
|
|
21628
|
+
return {
|
|
21629
|
+
...state,
|
|
21630
|
+
highContrast: action.payload
|
|
21631
|
+
};
|
|
21632
|
+
case 'SET_REDUCED_MOTION':
|
|
21633
|
+
return {
|
|
21634
|
+
...state,
|
|
21635
|
+
reducedMotion: action.payload
|
|
21636
|
+
};
|
|
21637
|
+
case 'SET_LARGE_TEXT':
|
|
21638
|
+
return {
|
|
21639
|
+
...state,
|
|
21640
|
+
largeText: action.payload
|
|
21641
|
+
};
|
|
21642
|
+
case 'SET_FOCUS_VISIBLE':
|
|
21643
|
+
return {
|
|
21644
|
+
...state,
|
|
21645
|
+
focusVisible: action.payload
|
|
21646
|
+
};
|
|
21647
|
+
case 'SET_KEYBOARD_USER':
|
|
21648
|
+
return {
|
|
21649
|
+
...state,
|
|
21650
|
+
isKeyboardUser: action.payload
|
|
21651
|
+
};
|
|
21652
|
+
case 'ADD_ISSUE':
|
|
21653
|
+
return {
|
|
21654
|
+
...state,
|
|
21655
|
+
issues: [...state.issues, action.payload]
|
|
21656
|
+
};
|
|
21657
|
+
case 'CLEAR_ISSUES':
|
|
21658
|
+
return {
|
|
21659
|
+
...state,
|
|
21660
|
+
issues: []
|
|
21661
|
+
};
|
|
21662
|
+
case 'SET_ANNOUNCEMENT':
|
|
21663
|
+
return {
|
|
21664
|
+
...state,
|
|
21665
|
+
lastAnnouncement: action.payload
|
|
21666
|
+
};
|
|
21667
|
+
default:
|
|
21668
|
+
return state;
|
|
21669
|
+
}
|
|
21670
|
+
};
|
|
21671
|
+
// Initial state
|
|
21672
|
+
const initialState = {
|
|
21673
|
+
highContrast: false,
|
|
21674
|
+
reducedMotion: false,
|
|
21675
|
+
largeText: false,
|
|
21676
|
+
focusVisible: true,
|
|
21677
|
+
isKeyboardUser: false,
|
|
21678
|
+
issues: [],
|
|
21679
|
+
lastAnnouncement: null,
|
|
21680
|
+
preferences: {}
|
|
21681
|
+
};
|
|
21682
|
+
// ARIA Live Manager
|
|
21683
|
+
class AriaLiveManager {
|
|
21684
|
+
constructor() {
|
|
21685
|
+
this.politeRegion = null;
|
|
21686
|
+
this.assertiveRegion = null;
|
|
21687
|
+
this.createLiveRegions();
|
|
21688
|
+
}
|
|
21689
|
+
createLiveRegions() {
|
|
21690
|
+
if (typeof document === 'undefined') return;
|
|
21691
|
+
// Polite announcements
|
|
21692
|
+
this.politeRegion = document.createElement('div');
|
|
21693
|
+
this.politeRegion.setAttribute('aria-live', 'polite');
|
|
21694
|
+
this.politeRegion.setAttribute('aria-atomic', 'true');
|
|
21695
|
+
this.politeRegion.setAttribute('id', 'qwickapps-aria-live-polite');
|
|
21696
|
+
this.politeRegion.style.cssText = `
|
|
21697
|
+
position: absolute !important;
|
|
21698
|
+
left: -10000px !important;
|
|
21699
|
+
width: 1px !important;
|
|
21700
|
+
height: 1px !important;
|
|
21701
|
+
overflow: hidden !important;
|
|
21702
|
+
`;
|
|
21703
|
+
document.body.appendChild(this.politeRegion);
|
|
21704
|
+
// Assertive announcements
|
|
21705
|
+
this.assertiveRegion = document.createElement('div');
|
|
21706
|
+
this.assertiveRegion.setAttribute('aria-live', 'assertive');
|
|
21707
|
+
this.assertiveRegion.setAttribute('aria-atomic', 'true');
|
|
21708
|
+
this.assertiveRegion.setAttribute('id', 'qwickapps-aria-live-assertive');
|
|
21709
|
+
this.assertiveRegion.style.cssText = `
|
|
21710
|
+
position: absolute !important;
|
|
21711
|
+
left: -10000px !important;
|
|
21712
|
+
width: 1px !important;
|
|
21713
|
+
height: 1px !important;
|
|
21714
|
+
overflow: hidden !important;
|
|
21715
|
+
`;
|
|
21716
|
+
document.body.appendChild(this.assertiveRegion);
|
|
21717
|
+
}
|
|
21718
|
+
announce(message, level = 'polite') {
|
|
21719
|
+
if (level === 'assertive') {
|
|
21720
|
+
this.announceAssertive(message);
|
|
21721
|
+
} else {
|
|
21722
|
+
this.announcePolite(message);
|
|
21723
|
+
}
|
|
21724
|
+
}
|
|
21725
|
+
announcePolite(message) {
|
|
21726
|
+
if (!this.politeRegion) return;
|
|
21727
|
+
this.politeRegion.textContent = '';
|
|
21728
|
+
// Small delay ensures screen readers detect the change
|
|
21729
|
+
setTimeout(() => {
|
|
21730
|
+
if (this.politeRegion) {
|
|
21731
|
+
this.politeRegion.textContent = message;
|
|
21732
|
+
}
|
|
21733
|
+
}, 100);
|
|
21734
|
+
}
|
|
21735
|
+
announceAssertive(message) {
|
|
21736
|
+
if (!this.assertiveRegion) return;
|
|
21737
|
+
this.assertiveRegion.textContent = '';
|
|
21738
|
+
// Small delay ensures screen readers detect the change
|
|
21739
|
+
setTimeout(() => {
|
|
21740
|
+
if (this.assertiveRegion) {
|
|
21741
|
+
this.assertiveRegion.textContent = message;
|
|
21742
|
+
}
|
|
21743
|
+
}, 100);
|
|
21744
|
+
}
|
|
21745
|
+
}
|
|
21746
|
+
const ariaLiveManager = new AriaLiveManager();
|
|
21747
|
+
/**
|
|
21748
|
+
* Accessibility Provider Component
|
|
21749
|
+
* Provides comprehensive accessibility context and utilities
|
|
21750
|
+
*
|
|
21751
|
+
* Features:
|
|
21752
|
+
* - System preference detection (high contrast, reduced motion)
|
|
21753
|
+
* - Keyboard navigation detection
|
|
21754
|
+
* - ARIA live announcements
|
|
21755
|
+
* - Focus management
|
|
21756
|
+
* - Accessibility auditing
|
|
21757
|
+
* - Settings persistence
|
|
21758
|
+
*/
|
|
21759
|
+
const AccessibilityProvider = ({
|
|
21760
|
+
children,
|
|
21761
|
+
enableAudit = "development" === 'development'
|
|
21762
|
+
}) => {
|
|
21763
|
+
const [state, dispatch] = React.useReducer(accessibilityReducer, initialState);
|
|
21764
|
+
React.useEffect(() => {
|
|
21765
|
+
// Detect user preferences from system
|
|
21766
|
+
detectUserPreferences();
|
|
21767
|
+
// Set up keyboard detection
|
|
21768
|
+
const keyboardCleanup = setupKeyboardDetection();
|
|
21769
|
+
// Initialize focus management
|
|
21770
|
+
initializeFocusManagement();
|
|
21771
|
+
// Run initial accessibility audit
|
|
21772
|
+
if (enableAudit) {
|
|
21773
|
+
runAccessibilityAudit();
|
|
21774
|
+
}
|
|
21775
|
+
// Cleanup
|
|
21776
|
+
return () => {
|
|
21777
|
+
if (keyboardCleanup) keyboardCleanup();
|
|
21778
|
+
};
|
|
21779
|
+
}, [enableAudit]);
|
|
21780
|
+
const detectUserPreferences = () => {
|
|
21781
|
+
if (typeof window === 'undefined') return;
|
|
21782
|
+
// High contrast mode
|
|
21783
|
+
if (window.matchMedia && window.matchMedia('(prefers-contrast: high)').matches) {
|
|
21784
|
+
dispatch({
|
|
21785
|
+
type: 'SET_HIGH_CONTRAST',
|
|
21786
|
+
payload: true
|
|
21787
|
+
});
|
|
21788
|
+
}
|
|
21789
|
+
// Reduced motion
|
|
21790
|
+
if (window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
|
|
21791
|
+
dispatch({
|
|
21792
|
+
type: 'SET_REDUCED_MOTION',
|
|
21793
|
+
payload: true
|
|
21794
|
+
});
|
|
21795
|
+
}
|
|
21796
|
+
// Listen for changes
|
|
21797
|
+
if (window.matchMedia) {
|
|
21798
|
+
const contrastMedia = window.matchMedia('(prefers-contrast: high)');
|
|
21799
|
+
const motionMedia = window.matchMedia('(prefers-reduced-motion: reduce)');
|
|
21800
|
+
const contrastHandler = e => {
|
|
21801
|
+
dispatch({
|
|
21802
|
+
type: 'SET_HIGH_CONTRAST',
|
|
21803
|
+
payload: e.matches
|
|
21804
|
+
});
|
|
21805
|
+
};
|
|
21806
|
+
const motionHandler = e => {
|
|
21807
|
+
dispatch({
|
|
21808
|
+
type: 'SET_REDUCED_MOTION',
|
|
21809
|
+
payload: e.matches
|
|
21810
|
+
});
|
|
21811
|
+
};
|
|
21812
|
+
contrastMedia.addEventListener('change', contrastHandler);
|
|
21813
|
+
motionMedia.addEventListener('change', motionHandler);
|
|
21814
|
+
// Return cleanup function
|
|
21815
|
+
return () => {
|
|
21816
|
+
contrastMedia.removeEventListener('change', contrastHandler);
|
|
21817
|
+
motionMedia.removeEventListener('change', motionHandler);
|
|
21818
|
+
};
|
|
21819
|
+
}
|
|
21820
|
+
};
|
|
21821
|
+
const setupKeyboardDetection = () => {
|
|
21822
|
+
if (typeof document === 'undefined') return;
|
|
21823
|
+
let keyboardUser = false;
|
|
21824
|
+
const handleKeyDown = e => {
|
|
21825
|
+
if (e.key === 'Tab') {
|
|
21826
|
+
keyboardUser = true;
|
|
21827
|
+
dispatch({
|
|
21828
|
+
type: 'SET_KEYBOARD_USER',
|
|
21829
|
+
payload: true
|
|
21830
|
+
});
|
|
21831
|
+
document.body.classList.add('keyboard-user');
|
|
21832
|
+
}
|
|
21833
|
+
};
|
|
21834
|
+
const handleMouseDown = () => {
|
|
21835
|
+
if (keyboardUser) {
|
|
21836
|
+
keyboardUser = false;
|
|
21837
|
+
dispatch({
|
|
21838
|
+
type: 'SET_KEYBOARD_USER',
|
|
21839
|
+
payload: false
|
|
21840
|
+
});
|
|
21841
|
+
document.body.classList.remove('keyboard-user');
|
|
21842
|
+
}
|
|
21843
|
+
};
|
|
21844
|
+
document.addEventListener('keydown', handleKeyDown);
|
|
21845
|
+
document.addEventListener('mousedown', handleMouseDown);
|
|
21846
|
+
return () => {
|
|
21847
|
+
document.removeEventListener('keydown', handleKeyDown);
|
|
21848
|
+
document.removeEventListener('mousedown', handleMouseDown);
|
|
21849
|
+
};
|
|
21850
|
+
};
|
|
21851
|
+
const initializeFocusManagement = () => {
|
|
21852
|
+
if (typeof document === 'undefined') return;
|
|
21853
|
+
// Enhanced focus indicators for keyboard users
|
|
21854
|
+
const style = document.createElement('style');
|
|
21855
|
+
style.textContent = `
|
|
21856
|
+
.keyboard-user *:focus {
|
|
21857
|
+
outline: 3px solid #005cee !important;
|
|
21858
|
+
outline-offset: 2px !important;
|
|
21859
|
+
}
|
|
21860
|
+
|
|
21861
|
+
.high-contrast *:focus {
|
|
21862
|
+
outline: 3px solid #ffffff !important;
|
|
21863
|
+
outline-offset: 2px !important;
|
|
21864
|
+
box-shadow: 0 0 0 1px #000000 !important;
|
|
21865
|
+
}
|
|
21866
|
+
|
|
21867
|
+
.reduced-motion * {
|
|
21868
|
+
animation-duration: 0.01ms !important;
|
|
21869
|
+
animation-iteration-count: 1 !important;
|
|
21870
|
+
transition-duration: 0.01ms !important;
|
|
21871
|
+
}
|
|
21872
|
+
|
|
21873
|
+
.large-text {
|
|
21874
|
+
font-size: 1.2em !important;
|
|
21875
|
+
}
|
|
21876
|
+
`;
|
|
21877
|
+
document.head.appendChild(style);
|
|
21878
|
+
};
|
|
21879
|
+
const runAccessibilityAudit = () => {
|
|
21880
|
+
if (typeof document === 'undefined') return;
|
|
21881
|
+
setTimeout(() => {
|
|
21882
|
+
const issues = [];
|
|
21883
|
+
// Check for images without alt text
|
|
21884
|
+
const images = document.querySelectorAll('img:not([alt])');
|
|
21885
|
+
images.forEach(img => {
|
|
21886
|
+
issues.push({
|
|
21887
|
+
type: 'missing-alt-text',
|
|
21888
|
+
message: 'Image missing alt attribute',
|
|
21889
|
+
level: 'error',
|
|
21890
|
+
element: img
|
|
21891
|
+
});
|
|
21892
|
+
});
|
|
21893
|
+
// Check for buttons without accessible names
|
|
21894
|
+
const buttons = document.querySelectorAll('button:not([aria-label]):not([title])');
|
|
21895
|
+
buttons.forEach(button => {
|
|
21896
|
+
if (!button.textContent?.trim()) {
|
|
21897
|
+
issues.push({
|
|
21898
|
+
type: 'unnamed-button',
|
|
21899
|
+
message: 'Button missing accessible name',
|
|
21900
|
+
level: 'error',
|
|
21901
|
+
element: button
|
|
21902
|
+
});
|
|
21903
|
+
}
|
|
21904
|
+
});
|
|
21905
|
+
// Check for form inputs without labels
|
|
21906
|
+
const inputs = document.querySelectorAll('input:not([aria-label]):not([title])');
|
|
21907
|
+
inputs.forEach(input => {
|
|
21908
|
+
const id = input.getAttribute('id');
|
|
21909
|
+
if (id) {
|
|
21910
|
+
const label = document.querySelector(`label[for="${id}"]`);
|
|
21911
|
+
if (!label) {
|
|
21912
|
+
issues.push({
|
|
21913
|
+
type: 'unlabeled-input',
|
|
21914
|
+
message: 'Form input missing label',
|
|
21915
|
+
level: 'error',
|
|
21916
|
+
element: input
|
|
21917
|
+
});
|
|
21918
|
+
}
|
|
21919
|
+
} else {
|
|
21920
|
+
issues.push({
|
|
21921
|
+
type: 'unlabeled-input',
|
|
21922
|
+
message: 'Form input missing label',
|
|
21923
|
+
level: 'error',
|
|
21924
|
+
element: input
|
|
21925
|
+
});
|
|
21926
|
+
}
|
|
21927
|
+
});
|
|
21928
|
+
dispatch({
|
|
21929
|
+
type: 'CLEAR_ISSUES'
|
|
21930
|
+
});
|
|
21931
|
+
issues.forEach(issue => {
|
|
21932
|
+
dispatch({
|
|
21933
|
+
type: 'ADD_ISSUE',
|
|
21934
|
+
payload: issue
|
|
21935
|
+
});
|
|
21936
|
+
});
|
|
21937
|
+
if (issues.length > 0) {
|
|
21938
|
+
console.group('🔍 Accessibility Issues Found');
|
|
21939
|
+
issues.forEach(issue => {
|
|
21940
|
+
const logMethod = issue.level === 'error' ? console.error : console.warn;
|
|
21941
|
+
logMethod(`${issue.type}: ${issue.message}`);
|
|
21942
|
+
});
|
|
21943
|
+
console.groupEnd();
|
|
21944
|
+
}
|
|
21945
|
+
}, 1000);
|
|
21946
|
+
};
|
|
21947
|
+
// Context value
|
|
21948
|
+
const contextValue = {
|
|
21949
|
+
...state,
|
|
21950
|
+
// Actions
|
|
21951
|
+
setHighContrast: enabled => dispatch({
|
|
21952
|
+
type: 'SET_HIGH_CONTRAST',
|
|
21953
|
+
payload: enabled
|
|
21954
|
+
}),
|
|
21955
|
+
setReducedMotion: enabled => dispatch({
|
|
21956
|
+
type: 'SET_REDUCED_MOTION',
|
|
21957
|
+
payload: enabled
|
|
21958
|
+
}),
|
|
21959
|
+
setLargeText: enabled => dispatch({
|
|
21960
|
+
type: 'SET_LARGE_TEXT',
|
|
21961
|
+
payload: enabled
|
|
21962
|
+
}),
|
|
21963
|
+
setFocusVisible: enabled => dispatch({
|
|
21964
|
+
type: 'SET_FOCUS_VISIBLE',
|
|
21965
|
+
payload: enabled
|
|
21966
|
+
}),
|
|
21967
|
+
// Utilities
|
|
21968
|
+
announce: (message, level = 'polite') => {
|
|
21969
|
+
ariaLiveManager.announce(message, level);
|
|
21970
|
+
dispatch({
|
|
21971
|
+
type: 'SET_ANNOUNCEMENT',
|
|
21972
|
+
payload: {
|
|
21973
|
+
message,
|
|
21974
|
+
level,
|
|
21975
|
+
timestamp: Date.now()
|
|
21976
|
+
}
|
|
21977
|
+
});
|
|
21978
|
+
},
|
|
21979
|
+
announcePolite: message => {
|
|
21980
|
+
ariaLiveManager.announcePolite(message);
|
|
21981
|
+
dispatch({
|
|
21982
|
+
type: 'SET_ANNOUNCEMENT',
|
|
21983
|
+
payload: {
|
|
21984
|
+
message,
|
|
21985
|
+
level: 'polite',
|
|
21986
|
+
timestamp: Date.now()
|
|
21987
|
+
}
|
|
21988
|
+
});
|
|
21989
|
+
},
|
|
21990
|
+
announceAssertive: message => {
|
|
21991
|
+
ariaLiveManager.announceAssertive(message);
|
|
21992
|
+
dispatch({
|
|
21993
|
+
type: 'SET_ANNOUNCEMENT',
|
|
21994
|
+
payload: {
|
|
21995
|
+
message,
|
|
21996
|
+
level: 'assertive',
|
|
21997
|
+
timestamp: Date.now()
|
|
21998
|
+
}
|
|
21999
|
+
});
|
|
22000
|
+
},
|
|
22001
|
+
addIssue: issue => dispatch({
|
|
22002
|
+
type: 'ADD_ISSUE',
|
|
22003
|
+
payload: issue
|
|
22004
|
+
}),
|
|
22005
|
+
clearIssues: () => dispatch({
|
|
22006
|
+
type: 'CLEAR_ISSUES'
|
|
22007
|
+
}),
|
|
22008
|
+
// Audit function
|
|
22009
|
+
runAudit: runAccessibilityAudit
|
|
22010
|
+
};
|
|
22011
|
+
// Apply CSS classes based on preferences
|
|
22012
|
+
React.useEffect(() => {
|
|
22013
|
+
if (typeof document === 'undefined') return;
|
|
22014
|
+
const {
|
|
22015
|
+
highContrast,
|
|
22016
|
+
reducedMotion,
|
|
22017
|
+
largeText
|
|
22018
|
+
} = state;
|
|
22019
|
+
document.body.classList.toggle('high-contrast', highContrast);
|
|
22020
|
+
document.body.classList.toggle('reduced-motion', reducedMotion);
|
|
22021
|
+
document.body.classList.toggle('large-text', largeText);
|
|
22022
|
+
}, [state.highContrast, state.reducedMotion, state.largeText]);
|
|
22023
|
+
return jsxRuntime.jsx(AccessibilityContext.Provider, {
|
|
22024
|
+
value: contextValue,
|
|
22025
|
+
children: children
|
|
22026
|
+
});
|
|
22027
|
+
};
|
|
22028
|
+
/**
|
|
22029
|
+
* Hook to access accessibility context
|
|
22030
|
+
*/
|
|
22031
|
+
const useAccessibility = () => {
|
|
22032
|
+
const context = React.useContext(AccessibilityContext);
|
|
22033
|
+
if (!context) {
|
|
22034
|
+
throw new Error('useAccessibility must be used within an AccessibilityProvider');
|
|
22035
|
+
}
|
|
22036
|
+
return context;
|
|
22037
|
+
};
|
|
22038
|
+
/**
|
|
22039
|
+
* Higher-Order Component for accessibility enhancements
|
|
22040
|
+
*/
|
|
22041
|
+
const withAccessibility = WrappedComponent => {
|
|
22042
|
+
const AccessibilityEnhancedComponent = props => {
|
|
22043
|
+
const accessibility = useAccessibility();
|
|
22044
|
+
return jsxRuntime.jsx(WrappedComponent, {
|
|
22045
|
+
...props,
|
|
22046
|
+
accessibility: accessibility
|
|
22047
|
+
});
|
|
22048
|
+
};
|
|
22049
|
+
AccessibilityEnhancedComponent.displayName = `withAccessibility(${WrappedComponent.displayName || WrappedComponent.name || 'Component'})`;
|
|
22050
|
+
return AccessibilityEnhancedComponent;
|
|
22051
|
+
};
|
|
22052
|
+
|
|
20584
22053
|
const QwickApp = ({
|
|
20585
22054
|
children,
|
|
20586
22055
|
className,
|
|
@@ -20642,16 +22111,20 @@ const QwickApp = ({
|
|
|
20642
22111
|
dataSource: dataSource,
|
|
20643
22112
|
children: content
|
|
20644
22113
|
}) : content;
|
|
20645
|
-
const appContent = jsxRuntime.jsx(
|
|
20646
|
-
|
|
20647
|
-
|
|
20648
|
-
|
|
20649
|
-
|
|
20650
|
-
|
|
20651
|
-
|
|
20652
|
-
|
|
20653
|
-
|
|
20654
|
-
|
|
22114
|
+
const appContent = jsxRuntime.jsx(ErrorBoundary, {
|
|
22115
|
+
children: jsxRuntime.jsx(AccessibilityProvider, {
|
|
22116
|
+
children: jsxRuntime.jsx("div", {
|
|
22117
|
+
className: `qwick-app ${className || ''}`,
|
|
22118
|
+
style: style,
|
|
22119
|
+
children: jsxRuntime.jsx(ThemeProvider, {
|
|
22120
|
+
appId: appId,
|
|
22121
|
+
defaultTheme: defaultTheme,
|
|
22122
|
+
defaultPalette: defaultPalette,
|
|
22123
|
+
children: jsxRuntime.jsx(QwickAppContext.Provider, {
|
|
22124
|
+
value: contextValue,
|
|
22125
|
+
children: wrappedContent
|
|
22126
|
+
})
|
|
22127
|
+
})
|
|
20655
22128
|
})
|
|
20656
22129
|
})
|
|
20657
22130
|
});
|
|
@@ -20759,6 +22232,186 @@ const setCSSVariable = (property, value) => {
|
|
|
20759
22232
|
document.documentElement.style.setProperty(property, value);
|
|
20760
22233
|
};
|
|
20761
22234
|
|
|
22235
|
+
/**
|
|
22236
|
+
* Generic Breadcrumbs component for navigation hierarchy
|
|
22237
|
+
*
|
|
22238
|
+
* Features:
|
|
22239
|
+
* - Accessible navigation with proper ARIA labels
|
|
22240
|
+
* - Customizable separators and icons
|
|
22241
|
+
* - Responsive design with item truncation
|
|
22242
|
+
* - Support for custom navigation handlers
|
|
22243
|
+
* - Keyboard navigation support
|
|
22244
|
+
* - Screen reader friendly
|
|
22245
|
+
*/
|
|
22246
|
+
const Breadcrumbs = ({
|
|
22247
|
+
items,
|
|
22248
|
+
separator = '/',
|
|
22249
|
+
className = '',
|
|
22250
|
+
onNavigate,
|
|
22251
|
+
maxItems,
|
|
22252
|
+
showRoot = true
|
|
22253
|
+
}) => {
|
|
22254
|
+
// Filter and prepare items
|
|
22255
|
+
let displayItems = showRoot ? items : items.slice(1);
|
|
22256
|
+
// Handle max items with ellipsis
|
|
22257
|
+
if (maxItems && displayItems.length > maxItems) {
|
|
22258
|
+
const firstItems = displayItems.slice(0, 1);
|
|
22259
|
+
const lastItems = displayItems.slice(-Math.max(1, maxItems - 2));
|
|
22260
|
+
displayItems = [...firstItems, {
|
|
22261
|
+
label: '...',
|
|
22262
|
+
href: undefined,
|
|
22263
|
+
current: false
|
|
22264
|
+
}, ...lastItems];
|
|
22265
|
+
}
|
|
22266
|
+
const handleItemClick = (e, item, index) => {
|
|
22267
|
+
if (onNavigate) {
|
|
22268
|
+
e.preventDefault();
|
|
22269
|
+
onNavigate(item, index);
|
|
22270
|
+
}
|
|
22271
|
+
};
|
|
22272
|
+
const handleKeyDown = (e, item, index) => {
|
|
22273
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
22274
|
+
e.preventDefault();
|
|
22275
|
+
if (onNavigate) {
|
|
22276
|
+
onNavigate(item, index);
|
|
22277
|
+
} else if (item.href) {
|
|
22278
|
+
window.location.href = item.href;
|
|
22279
|
+
}
|
|
22280
|
+
}
|
|
22281
|
+
};
|
|
22282
|
+
if (displayItems.length <= 1) {
|
|
22283
|
+
return null;
|
|
22284
|
+
}
|
|
22285
|
+
return jsxRuntime.jsx("nav", {
|
|
22286
|
+
className: `breadcrumbs ${className}`,
|
|
22287
|
+
role: "navigation",
|
|
22288
|
+
"aria-label": "Breadcrumb navigation",
|
|
22289
|
+
style: {
|
|
22290
|
+
display: 'flex',
|
|
22291
|
+
alignItems: 'center',
|
|
22292
|
+
fontSize: '14px',
|
|
22293
|
+
color: '#6b7280',
|
|
22294
|
+
...defaultStyles.nav
|
|
22295
|
+
},
|
|
22296
|
+
children: jsxRuntime.jsx("ol", {
|
|
22297
|
+
style: {
|
|
22298
|
+
display: 'flex',
|
|
22299
|
+
alignItems: 'center',
|
|
22300
|
+
listStyle: 'none',
|
|
22301
|
+
margin: 0,
|
|
22302
|
+
padding: 0,
|
|
22303
|
+
gap: '8px'
|
|
22304
|
+
},
|
|
22305
|
+
children: displayItems.map((item, index) => {
|
|
22306
|
+
const isLast = index === displayItems.length - 1;
|
|
22307
|
+
const isClickable = (item.href || onNavigate) && !item.current && item.label !== '...';
|
|
22308
|
+
return jsxRuntime.jsxs("li", {
|
|
22309
|
+
style: {
|
|
22310
|
+
display: 'flex',
|
|
22311
|
+
alignItems: 'center'
|
|
22312
|
+
},
|
|
22313
|
+
children: [isClickable ? jsxRuntime.jsxs("a", {
|
|
22314
|
+
href: item.href,
|
|
22315
|
+
onClick: e => handleItemClick(e, item, index),
|
|
22316
|
+
onKeyDown: e => handleKeyDown(e, item, index),
|
|
22317
|
+
style: {
|
|
22318
|
+
...defaultStyles.link,
|
|
22319
|
+
color: isLast ? '#374151' : '#6b7280',
|
|
22320
|
+
textDecoration: 'none',
|
|
22321
|
+
display: 'flex',
|
|
22322
|
+
alignItems: 'center',
|
|
22323
|
+
gap: '4px'
|
|
22324
|
+
},
|
|
22325
|
+
tabIndex: 0,
|
|
22326
|
+
"aria-current": item.current ? 'page' : undefined,
|
|
22327
|
+
children: [item.icon && jsxRuntime.jsx("span", {
|
|
22328
|
+
style: {
|
|
22329
|
+
display: 'flex',
|
|
22330
|
+
alignItems: 'center'
|
|
22331
|
+
},
|
|
22332
|
+
"aria-hidden": "true",
|
|
22333
|
+
children: item.icon
|
|
22334
|
+
}), jsxRuntime.jsx("span", {
|
|
22335
|
+
children: item.label
|
|
22336
|
+
})]
|
|
22337
|
+
}) : jsxRuntime.jsxs("span", {
|
|
22338
|
+
style: {
|
|
22339
|
+
...defaultStyles.current,
|
|
22340
|
+
color: isLast ? '#111827' : '#6b7280',
|
|
22341
|
+
fontWeight: isLast ? 600 : 400,
|
|
22342
|
+
display: 'flex',
|
|
22343
|
+
alignItems: 'center',
|
|
22344
|
+
gap: '4px'
|
|
22345
|
+
},
|
|
22346
|
+
"aria-current": item.current ? 'page' : undefined,
|
|
22347
|
+
children: [item.icon && jsxRuntime.jsx("span", {
|
|
22348
|
+
style: {
|
|
22349
|
+
display: 'flex',
|
|
22350
|
+
alignItems: 'center'
|
|
22351
|
+
},
|
|
22352
|
+
"aria-hidden": "true",
|
|
22353
|
+
children: item.icon
|
|
22354
|
+
}), jsxRuntime.jsx("span", {
|
|
22355
|
+
children: item.label
|
|
22356
|
+
})]
|
|
22357
|
+
}), !isLast && jsxRuntime.jsx("span", {
|
|
22358
|
+
style: {
|
|
22359
|
+
display: 'flex',
|
|
22360
|
+
alignItems: 'center',
|
|
22361
|
+
marginLeft: '8px',
|
|
22362
|
+
color: '#d1d5db',
|
|
22363
|
+
fontSize: '12px'
|
|
22364
|
+
},
|
|
22365
|
+
"aria-hidden": "true",
|
|
22366
|
+
children: separator
|
|
22367
|
+
})]
|
|
22368
|
+
}, `${item.label}-${index}`);
|
|
22369
|
+
})
|
|
22370
|
+
})
|
|
22371
|
+
});
|
|
22372
|
+
};
|
|
22373
|
+
// Default styles
|
|
22374
|
+
const defaultStyles = {
|
|
22375
|
+
nav: {
|
|
22376
|
+
padding: '8px 0'
|
|
22377
|
+
},
|
|
22378
|
+
link: {
|
|
22379
|
+
transition: 'color 0.2s ease',
|
|
22380
|
+
cursor: 'pointer',
|
|
22381
|
+
borderRadius: '4px',
|
|
22382
|
+
padding: '4px',
|
|
22383
|
+
margin: '-4px'
|
|
22384
|
+
},
|
|
22385
|
+
current: {
|
|
22386
|
+
padding: '4px'
|
|
22387
|
+
}
|
|
22388
|
+
};
|
|
22389
|
+
/**
|
|
22390
|
+
* Hook for managing breadcrumb state
|
|
22391
|
+
*/
|
|
22392
|
+
const useBreadcrumbs = () => {
|
|
22393
|
+
const [breadcrumbs, setBreadcrumbs] = React.useState([]);
|
|
22394
|
+
const addBreadcrumb = React.useCallback(item => {
|
|
22395
|
+
setBreadcrumbs(prev => [...prev, item]);
|
|
22396
|
+
}, []);
|
|
22397
|
+
const removeBreadcrumb = React.useCallback(index => {
|
|
22398
|
+
setBreadcrumbs(prev => prev.filter((_, i) => i !== index));
|
|
22399
|
+
}, []);
|
|
22400
|
+
const setBreadcrumbsCurrent = React.useCallback(items => {
|
|
22401
|
+
setBreadcrumbs(items);
|
|
22402
|
+
}, []);
|
|
22403
|
+
const clearBreadcrumbs = React.useCallback(() => {
|
|
22404
|
+
setBreadcrumbs([]);
|
|
22405
|
+
}, []);
|
|
22406
|
+
return {
|
|
22407
|
+
breadcrumbs,
|
|
22408
|
+
addBreadcrumb,
|
|
22409
|
+
removeBreadcrumb,
|
|
22410
|
+
setBreadcrumbs: setBreadcrumbsCurrent,
|
|
22411
|
+
clearBreadcrumbs
|
|
22412
|
+
};
|
|
22413
|
+
};
|
|
22414
|
+
|
|
20762
22415
|
const QwickAppsLogo = props => {
|
|
20763
22416
|
const {
|
|
20764
22417
|
styleProps,
|
|
@@ -24226,18 +25879,23 @@ exports.ActionType = void 0;
|
|
|
24226
25879
|
})(exports.ActionType || (exports.ActionType = {}));
|
|
24227
25880
|
|
|
24228
25881
|
exports.AVAILABLE_PALETTES = AVAILABLE_PALETTES;
|
|
25882
|
+
exports.AccessibilityProvider = AccessibilityProvider;
|
|
24229
25883
|
exports.AllPalettes = AllPalettes;
|
|
24230
25884
|
exports.Article = Article;
|
|
24231
25885
|
exports.BasePage = BasePage;
|
|
25886
|
+
exports.Breadcrumbs = Breadcrumbs;
|
|
24232
25887
|
exports.Button = Button;
|
|
24233
25888
|
exports.CardListGrid = CardListGrid;
|
|
24234
25889
|
exports.ChoiceInputField = ChoiceInputField;
|
|
24235
25890
|
exports.Code = Code;
|
|
25891
|
+
exports.CollapsibleLayout = CollapsibleLayout;
|
|
25892
|
+
exports.CollapsibleLayoutView = CollapsibleLayoutView;
|
|
24236
25893
|
exports.Content = Content;
|
|
24237
25894
|
exports.CoverImageHeader = CoverImageHeader;
|
|
24238
25895
|
exports.DataProvider = DataProvider;
|
|
24239
25896
|
exports.DataProxy = DataProxy;
|
|
24240
25897
|
exports.DimensionsProvider = DimensionsProvider;
|
|
25898
|
+
exports.ErrorBoundary = ErrorBoundary;
|
|
24241
25899
|
exports.FeatureCard = FeatureCard;
|
|
24242
25900
|
exports.FeatureGrid = FeatureGrid;
|
|
24243
25901
|
exports.Footer = Footer;
|
|
@@ -24267,16 +25925,19 @@ exports.QwickAppsLogo = QwickAppsLogo;
|
|
|
24267
25925
|
exports.SafeSpan = SafeSpan;
|
|
24268
25926
|
exports.Section = Section;
|
|
24269
25927
|
exports.SelectInputField = SelectInputField;
|
|
25928
|
+
exports.SwitchInputField = SwitchInputField;
|
|
24270
25929
|
exports.T = T;
|
|
24271
25930
|
exports.TextField = TextField;
|
|
24272
25931
|
exports.TextInputField = TextInputField;
|
|
24273
25932
|
exports.ThemeProvider = ThemeProvider;
|
|
24274
25933
|
exports.ThemeSwitcher = ThemeSwitcher;
|
|
25934
|
+
exports.animationConfigs = animationConfigs;
|
|
24275
25935
|
exports.applyCustomPalette = applyCustomPalette;
|
|
24276
25936
|
exports.clearUserPalettePreference = clearUserPalettePreference;
|
|
24277
25937
|
exports.clearUserThemePreference = clearUserThemePreference;
|
|
24278
25938
|
exports.createLogger = createLogger;
|
|
24279
25939
|
exports.createPaletteFromCurrentTheme = createPaletteFromCurrentTheme;
|
|
25940
|
+
exports.defaultCollapsibleLayoutProps = defaultCollapsibleLayoutProps;
|
|
24280
25941
|
exports.deleteCustomPalette = deleteCustomPalette;
|
|
24281
25942
|
exports.exportPalette = exportPalette;
|
|
24282
25943
|
exports.getCSSVariable = getCSSVariable;
|
|
@@ -24291,6 +25952,7 @@ exports.getThemePerformanceStats = getThemePerformanceStats;
|
|
|
24291
25952
|
exports.importPalette = importPalette;
|
|
24292
25953
|
exports.initializePalette = initializePalette;
|
|
24293
25954
|
exports.initializeTheme = initializeTheme;
|
|
25955
|
+
exports.isCollapsibleLayoutProps = isCollapsibleLayoutProps;
|
|
24294
25956
|
exports.loadUserPalettePreference = loadUserPalettePreference;
|
|
24295
25957
|
exports.loadUserThemePreference = loadUserThemePreference;
|
|
24296
25958
|
exports.logThemePerformanceStats = logThemePerformanceStats;
|
|
@@ -24308,8 +25970,12 @@ exports.saveUserThemePreference = saveUserThemePreference;
|
|
|
24308
25970
|
exports.setCSSVariable = setCSSVariable;
|
|
24309
25971
|
exports.setPalette = setPalette;
|
|
24310
25972
|
exports.setTheme = setTheme;
|
|
25973
|
+
exports.spacingConfigs = spacingConfigs;
|
|
24311
25974
|
exports.t = t;
|
|
25975
|
+
exports.useAccessibility = useAccessibility;
|
|
24312
25976
|
exports.useBaseProps = useBaseProps;
|
|
25977
|
+
exports.useBreadcrumbs = useBreadcrumbs;
|
|
25978
|
+
exports.useCollapsibleState = useCollapsibleState;
|
|
24313
25979
|
exports.useData = useData;
|
|
24314
25980
|
exports.useDataBinding = useDataBinding;
|
|
24315
25981
|
exports.useDataContext = useDataContext;
|
|
@@ -24322,3 +25988,5 @@ exports.useSafeLocation = useSafeLocation;
|
|
|
24322
25988
|
exports.useSafeNavigate = useSafeNavigate;
|
|
24323
25989
|
exports.useTemplate = useTemplate;
|
|
24324
25990
|
exports.useTheme = useTheme;
|
|
25991
|
+
exports.withAccessibility = withAccessibility;
|
|
25992
|
+
exports.withErrorBoundary = withErrorBoundary;
|