@qwickapps/react-framework 1.3.2 → 1.3.3
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 +106 -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/index.d.ts +3 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/index.bundled.css +12 -0
- package/dist/index.esm.js +795 -12
- package/dist/index.js +800 -10
- 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/index.ts +3 -0
- package/src/stories/AccessibilityProvider.stories.tsx +284 -0
- package/src/stories/Breadcrumbs.stories.tsx +304 -0
- package/src/stories/ErrorBoundary.stories.tsx +159 -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.esm.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
|
|
2
2
|
import { CircularProgress, Button as Button$1, Paper, Typography, useTheme as useTheme$1, Box, Container as Container$8, Stack, Tooltip, IconButton, Snackbar, Alert, useMediaQuery, Avatar, Chip, Menu, MenuItem, Grid, Divider, Link, ListItemIcon, ListItemText, Card, CardContent, ButtonGroup, Collapse, TextField as TextField$1, FormControl, InputLabel, Select, FormHelperText } from '@mui/material';
|
|
3
|
-
import React, { useMemo, useContext, useState, useEffect, createContext, useRef, useCallback, cloneElement } from 'react';
|
|
3
|
+
import React, { useMemo, useContext, useState, useEffect, createContext, useRef, useCallback, Component, useReducer, cloneElement } from 'react';
|
|
4
4
|
import { MustacheTemplateProvider, MemoryCacheProvider, CachedDataProvider, Field, Editor, FieldType, Schema, Model, DataType } from '@qwickapps/schema';
|
|
5
5
|
import { IsOptional, IsString, IsIn, IsUrl, IsArray, ValidateNested, IsNumber, Min, Max, IsBoolean, IsNotEmpty, IsObject } from 'class-validator';
|
|
6
6
|
import { Type } from 'class-transformer';
|
|
@@ -20579,6 +20579,605 @@ const Scaffold = ({
|
|
|
20579
20579
|
|
|
20580
20580
|
loggers.menu;
|
|
20581
20581
|
|
|
20582
|
+
/**
|
|
20583
|
+
* Generic ErrorBoundary component for catching and handling React errors
|
|
20584
|
+
*
|
|
20585
|
+
* Features:
|
|
20586
|
+
* - Catches JavaScript errors anywhere in child component tree
|
|
20587
|
+
* - Displays fallback UI with retry functionality
|
|
20588
|
+
* - Shows error details in development mode
|
|
20589
|
+
* - Customizable error handling and fallback UI
|
|
20590
|
+
* - Automatic error logging
|
|
20591
|
+
*/
|
|
20592
|
+
class ErrorBoundary extends Component {
|
|
20593
|
+
constructor(props) {
|
|
20594
|
+
super(props);
|
|
20595
|
+
this.handleRetry = () => {
|
|
20596
|
+
this.setState({
|
|
20597
|
+
hasError: false,
|
|
20598
|
+
error: null,
|
|
20599
|
+
errorInfo: null
|
|
20600
|
+
});
|
|
20601
|
+
};
|
|
20602
|
+
this.handleRefresh = () => {
|
|
20603
|
+
if (typeof window !== 'undefined') {
|
|
20604
|
+
window.location.reload();
|
|
20605
|
+
}
|
|
20606
|
+
};
|
|
20607
|
+
this.state = {
|
|
20608
|
+
hasError: false,
|
|
20609
|
+
error: null,
|
|
20610
|
+
errorInfo: null
|
|
20611
|
+
};
|
|
20612
|
+
}
|
|
20613
|
+
static getDerivedStateFromError(error) {
|
|
20614
|
+
// Update state so the next render will show the fallback UI
|
|
20615
|
+
return {
|
|
20616
|
+
hasError: true,
|
|
20617
|
+
error,
|
|
20618
|
+
errorInfo: null
|
|
20619
|
+
};
|
|
20620
|
+
}
|
|
20621
|
+
componentDidCatch(error, errorInfo) {
|
|
20622
|
+
// Log error details
|
|
20623
|
+
this.setState({
|
|
20624
|
+
error,
|
|
20625
|
+
errorInfo
|
|
20626
|
+
});
|
|
20627
|
+
// Log to console for debugging
|
|
20628
|
+
console.error('ErrorBoundary caught an error:', error, errorInfo);
|
|
20629
|
+
// Custom error handler
|
|
20630
|
+
if (this.props.onError) {
|
|
20631
|
+
this.props.onError(error, errorInfo);
|
|
20632
|
+
}
|
|
20633
|
+
// Send error to logging service if available
|
|
20634
|
+
if (typeof window !== 'undefined') {
|
|
20635
|
+
// @ts-ignore - Global error logging service
|
|
20636
|
+
if (window.qwickapps?.logError) {
|
|
20637
|
+
window.qwickapps.logError(error, errorInfo);
|
|
20638
|
+
}
|
|
20639
|
+
}
|
|
20640
|
+
}
|
|
20641
|
+
render() {
|
|
20642
|
+
if (this.state.hasError) {
|
|
20643
|
+
// Custom fallback UI
|
|
20644
|
+
if (this.props.fallback) {
|
|
20645
|
+
return this.props.fallback;
|
|
20646
|
+
}
|
|
20647
|
+
// Default error UI
|
|
20648
|
+
return jsxs("div", {
|
|
20649
|
+
className: "error-boundary",
|
|
20650
|
+
role: "alert",
|
|
20651
|
+
style: {
|
|
20652
|
+
padding: '2rem',
|
|
20653
|
+
textAlign: 'center',
|
|
20654
|
+
backgroundColor: '#fef2f2',
|
|
20655
|
+
border: '1px solid #fecaca',
|
|
20656
|
+
borderRadius: '8px',
|
|
20657
|
+
margin: '1rem',
|
|
20658
|
+
color: '#991b1b'
|
|
20659
|
+
},
|
|
20660
|
+
children: [jsxs("div", {
|
|
20661
|
+
style: {
|
|
20662
|
+
marginBottom: '1.5rem'
|
|
20663
|
+
},
|
|
20664
|
+
children: [jsx("h2", {
|
|
20665
|
+
style: {
|
|
20666
|
+
fontSize: '1.5rem',
|
|
20667
|
+
fontWeight: 'bold',
|
|
20668
|
+
marginBottom: '0.5rem',
|
|
20669
|
+
color: '#991b1b'
|
|
20670
|
+
},
|
|
20671
|
+
children: "Something went wrong"
|
|
20672
|
+
}), jsx("p", {
|
|
20673
|
+
style: {
|
|
20674
|
+
color: '#7f1d1d',
|
|
20675
|
+
marginBottom: '1rem'
|
|
20676
|
+
},
|
|
20677
|
+
children: "An unexpected error occurred in the application. Please try again or refresh the page."
|
|
20678
|
+
})]
|
|
20679
|
+
}), jsxs("div", {
|
|
20680
|
+
style: {
|
|
20681
|
+
display: 'flex',
|
|
20682
|
+
gap: '0.75rem',
|
|
20683
|
+
justifyContent: 'center',
|
|
20684
|
+
marginBottom: '1rem'
|
|
20685
|
+
},
|
|
20686
|
+
children: [jsx(Button, {
|
|
20687
|
+
variant: "contained",
|
|
20688
|
+
onClick: this.handleRetry,
|
|
20689
|
+
style: {
|
|
20690
|
+
backgroundColor: '#dc2626',
|
|
20691
|
+
color: 'white'
|
|
20692
|
+
},
|
|
20693
|
+
children: "Try Again"
|
|
20694
|
+
}), jsx(Button, {
|
|
20695
|
+
variant: "outlined",
|
|
20696
|
+
onClick: this.handleRefresh,
|
|
20697
|
+
style: {
|
|
20698
|
+
borderColor: '#dc2626',
|
|
20699
|
+
color: '#dc2626'
|
|
20700
|
+
},
|
|
20701
|
+
children: "Refresh Page"
|
|
20702
|
+
})]
|
|
20703
|
+
}), this.state.error && jsxs("details", {
|
|
20704
|
+
style: {
|
|
20705
|
+
textAlign: 'left',
|
|
20706
|
+
marginTop: '1rem',
|
|
20707
|
+
padding: '1rem',
|
|
20708
|
+
backgroundColor: '#f9fafb',
|
|
20709
|
+
border: '1px solid #d1d5db',
|
|
20710
|
+
borderRadius: '6px'
|
|
20711
|
+
},
|
|
20712
|
+
children: [jsx("summary", {
|
|
20713
|
+
style: {
|
|
20714
|
+
cursor: 'pointer',
|
|
20715
|
+
fontWeight: 'bold',
|
|
20716
|
+
marginBottom: '0.5rem',
|
|
20717
|
+
color: '#374151'
|
|
20718
|
+
},
|
|
20719
|
+
children: "Error Details (Development Mode)"
|
|
20720
|
+
}), jsxs("pre", {
|
|
20721
|
+
style: {
|
|
20722
|
+
fontSize: '0.75rem',
|
|
20723
|
+
color: '#374151',
|
|
20724
|
+
whiteSpace: 'pre-wrap',
|
|
20725
|
+
overflow: 'auto'
|
|
20726
|
+
},
|
|
20727
|
+
children: [this.state.error.toString(), this.state.errorInfo?.componentStack && jsxs(Fragment, {
|
|
20728
|
+
children: [jsx("br", {}), jsx("br", {}), "Component Stack:", this.state.errorInfo.componentStack]
|
|
20729
|
+
})]
|
|
20730
|
+
})]
|
|
20731
|
+
})]
|
|
20732
|
+
});
|
|
20733
|
+
}
|
|
20734
|
+
return this.props.children;
|
|
20735
|
+
}
|
|
20736
|
+
}
|
|
20737
|
+
/**
|
|
20738
|
+
* Higher-order component that wraps a component with ErrorBoundary
|
|
20739
|
+
*/
|
|
20740
|
+
function withErrorBoundary(WrappedComponent, errorBoundaryProps) {
|
|
20741
|
+
const WithErrorBoundaryComponent = props => jsx(ErrorBoundary, {
|
|
20742
|
+
...errorBoundaryProps,
|
|
20743
|
+
children: jsx(WrappedComponent, {
|
|
20744
|
+
...props
|
|
20745
|
+
})
|
|
20746
|
+
});
|
|
20747
|
+
WithErrorBoundaryComponent.displayName = `withErrorBoundary(${WrappedComponent.displayName || WrappedComponent.name || 'Component'})`;
|
|
20748
|
+
return WithErrorBoundaryComponent;
|
|
20749
|
+
}
|
|
20750
|
+
|
|
20751
|
+
const AccessibilityContext = /*#__PURE__*/createContext(null);
|
|
20752
|
+
// Reducer
|
|
20753
|
+
const accessibilityReducer = (state, action) => {
|
|
20754
|
+
switch (action.type) {
|
|
20755
|
+
case 'SET_HIGH_CONTRAST':
|
|
20756
|
+
return {
|
|
20757
|
+
...state,
|
|
20758
|
+
highContrast: action.payload
|
|
20759
|
+
};
|
|
20760
|
+
case 'SET_REDUCED_MOTION':
|
|
20761
|
+
return {
|
|
20762
|
+
...state,
|
|
20763
|
+
reducedMotion: action.payload
|
|
20764
|
+
};
|
|
20765
|
+
case 'SET_LARGE_TEXT':
|
|
20766
|
+
return {
|
|
20767
|
+
...state,
|
|
20768
|
+
largeText: action.payload
|
|
20769
|
+
};
|
|
20770
|
+
case 'SET_FOCUS_VISIBLE':
|
|
20771
|
+
return {
|
|
20772
|
+
...state,
|
|
20773
|
+
focusVisible: action.payload
|
|
20774
|
+
};
|
|
20775
|
+
case 'SET_KEYBOARD_USER':
|
|
20776
|
+
return {
|
|
20777
|
+
...state,
|
|
20778
|
+
isKeyboardUser: action.payload
|
|
20779
|
+
};
|
|
20780
|
+
case 'ADD_ISSUE':
|
|
20781
|
+
return {
|
|
20782
|
+
...state,
|
|
20783
|
+
issues: [...state.issues, action.payload]
|
|
20784
|
+
};
|
|
20785
|
+
case 'CLEAR_ISSUES':
|
|
20786
|
+
return {
|
|
20787
|
+
...state,
|
|
20788
|
+
issues: []
|
|
20789
|
+
};
|
|
20790
|
+
case 'SET_ANNOUNCEMENT':
|
|
20791
|
+
return {
|
|
20792
|
+
...state,
|
|
20793
|
+
lastAnnouncement: action.payload
|
|
20794
|
+
};
|
|
20795
|
+
default:
|
|
20796
|
+
return state;
|
|
20797
|
+
}
|
|
20798
|
+
};
|
|
20799
|
+
// Initial state
|
|
20800
|
+
const initialState = {
|
|
20801
|
+
highContrast: false,
|
|
20802
|
+
reducedMotion: false,
|
|
20803
|
+
largeText: false,
|
|
20804
|
+
focusVisible: true,
|
|
20805
|
+
isKeyboardUser: false,
|
|
20806
|
+
issues: [],
|
|
20807
|
+
lastAnnouncement: null,
|
|
20808
|
+
preferences: {}
|
|
20809
|
+
};
|
|
20810
|
+
// ARIA Live Manager
|
|
20811
|
+
class AriaLiveManager {
|
|
20812
|
+
constructor() {
|
|
20813
|
+
this.politeRegion = null;
|
|
20814
|
+
this.assertiveRegion = null;
|
|
20815
|
+
this.createLiveRegions();
|
|
20816
|
+
}
|
|
20817
|
+
createLiveRegions() {
|
|
20818
|
+
if (typeof document === 'undefined') return;
|
|
20819
|
+
// Polite announcements
|
|
20820
|
+
this.politeRegion = document.createElement('div');
|
|
20821
|
+
this.politeRegion.setAttribute('aria-live', 'polite');
|
|
20822
|
+
this.politeRegion.setAttribute('aria-atomic', 'true');
|
|
20823
|
+
this.politeRegion.setAttribute('id', 'qwickapps-aria-live-polite');
|
|
20824
|
+
this.politeRegion.style.cssText = `
|
|
20825
|
+
position: absolute !important;
|
|
20826
|
+
left: -10000px !important;
|
|
20827
|
+
width: 1px !important;
|
|
20828
|
+
height: 1px !important;
|
|
20829
|
+
overflow: hidden !important;
|
|
20830
|
+
`;
|
|
20831
|
+
document.body.appendChild(this.politeRegion);
|
|
20832
|
+
// Assertive announcements
|
|
20833
|
+
this.assertiveRegion = document.createElement('div');
|
|
20834
|
+
this.assertiveRegion.setAttribute('aria-live', 'assertive');
|
|
20835
|
+
this.assertiveRegion.setAttribute('aria-atomic', 'true');
|
|
20836
|
+
this.assertiveRegion.setAttribute('id', 'qwickapps-aria-live-assertive');
|
|
20837
|
+
this.assertiveRegion.style.cssText = `
|
|
20838
|
+
position: absolute !important;
|
|
20839
|
+
left: -10000px !important;
|
|
20840
|
+
width: 1px !important;
|
|
20841
|
+
height: 1px !important;
|
|
20842
|
+
overflow: hidden !important;
|
|
20843
|
+
`;
|
|
20844
|
+
document.body.appendChild(this.assertiveRegion);
|
|
20845
|
+
}
|
|
20846
|
+
announce(message, level = 'polite') {
|
|
20847
|
+
if (level === 'assertive') {
|
|
20848
|
+
this.announceAssertive(message);
|
|
20849
|
+
} else {
|
|
20850
|
+
this.announcePolite(message);
|
|
20851
|
+
}
|
|
20852
|
+
}
|
|
20853
|
+
announcePolite(message) {
|
|
20854
|
+
if (!this.politeRegion) return;
|
|
20855
|
+
this.politeRegion.textContent = '';
|
|
20856
|
+
// Small delay ensures screen readers detect the change
|
|
20857
|
+
setTimeout(() => {
|
|
20858
|
+
if (this.politeRegion) {
|
|
20859
|
+
this.politeRegion.textContent = message;
|
|
20860
|
+
}
|
|
20861
|
+
}, 100);
|
|
20862
|
+
}
|
|
20863
|
+
announceAssertive(message) {
|
|
20864
|
+
if (!this.assertiveRegion) return;
|
|
20865
|
+
this.assertiveRegion.textContent = '';
|
|
20866
|
+
// Small delay ensures screen readers detect the change
|
|
20867
|
+
setTimeout(() => {
|
|
20868
|
+
if (this.assertiveRegion) {
|
|
20869
|
+
this.assertiveRegion.textContent = message;
|
|
20870
|
+
}
|
|
20871
|
+
}, 100);
|
|
20872
|
+
}
|
|
20873
|
+
}
|
|
20874
|
+
const ariaLiveManager = new AriaLiveManager();
|
|
20875
|
+
/**
|
|
20876
|
+
* Accessibility Provider Component
|
|
20877
|
+
* Provides comprehensive accessibility context and utilities
|
|
20878
|
+
*
|
|
20879
|
+
* Features:
|
|
20880
|
+
* - System preference detection (high contrast, reduced motion)
|
|
20881
|
+
* - Keyboard navigation detection
|
|
20882
|
+
* - ARIA live announcements
|
|
20883
|
+
* - Focus management
|
|
20884
|
+
* - Accessibility auditing
|
|
20885
|
+
* - Settings persistence
|
|
20886
|
+
*/
|
|
20887
|
+
const AccessibilityProvider = ({
|
|
20888
|
+
children,
|
|
20889
|
+
enableAudit = "development" === 'development'
|
|
20890
|
+
}) => {
|
|
20891
|
+
const [state, dispatch] = useReducer(accessibilityReducer, initialState);
|
|
20892
|
+
useEffect(() => {
|
|
20893
|
+
// Detect user preferences from system
|
|
20894
|
+
detectUserPreferences();
|
|
20895
|
+
// Set up keyboard detection
|
|
20896
|
+
const keyboardCleanup = setupKeyboardDetection();
|
|
20897
|
+
// Initialize focus management
|
|
20898
|
+
initializeFocusManagement();
|
|
20899
|
+
// Run initial accessibility audit
|
|
20900
|
+
if (enableAudit) {
|
|
20901
|
+
runAccessibilityAudit();
|
|
20902
|
+
}
|
|
20903
|
+
// Cleanup
|
|
20904
|
+
return () => {
|
|
20905
|
+
if (keyboardCleanup) keyboardCleanup();
|
|
20906
|
+
};
|
|
20907
|
+
}, [enableAudit]);
|
|
20908
|
+
const detectUserPreferences = () => {
|
|
20909
|
+
if (typeof window === 'undefined') return;
|
|
20910
|
+
// High contrast mode
|
|
20911
|
+
if (window.matchMedia && window.matchMedia('(prefers-contrast: high)').matches) {
|
|
20912
|
+
dispatch({
|
|
20913
|
+
type: 'SET_HIGH_CONTRAST',
|
|
20914
|
+
payload: true
|
|
20915
|
+
});
|
|
20916
|
+
}
|
|
20917
|
+
// Reduced motion
|
|
20918
|
+
if (window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
|
|
20919
|
+
dispatch({
|
|
20920
|
+
type: 'SET_REDUCED_MOTION',
|
|
20921
|
+
payload: true
|
|
20922
|
+
});
|
|
20923
|
+
}
|
|
20924
|
+
// Listen for changes
|
|
20925
|
+
if (window.matchMedia) {
|
|
20926
|
+
const contrastMedia = window.matchMedia('(prefers-contrast: high)');
|
|
20927
|
+
const motionMedia = window.matchMedia('(prefers-reduced-motion: reduce)');
|
|
20928
|
+
const contrastHandler = e => {
|
|
20929
|
+
dispatch({
|
|
20930
|
+
type: 'SET_HIGH_CONTRAST',
|
|
20931
|
+
payload: e.matches
|
|
20932
|
+
});
|
|
20933
|
+
};
|
|
20934
|
+
const motionHandler = e => {
|
|
20935
|
+
dispatch({
|
|
20936
|
+
type: 'SET_REDUCED_MOTION',
|
|
20937
|
+
payload: e.matches
|
|
20938
|
+
});
|
|
20939
|
+
};
|
|
20940
|
+
contrastMedia.addEventListener('change', contrastHandler);
|
|
20941
|
+
motionMedia.addEventListener('change', motionHandler);
|
|
20942
|
+
// Return cleanup function
|
|
20943
|
+
return () => {
|
|
20944
|
+
contrastMedia.removeEventListener('change', contrastHandler);
|
|
20945
|
+
motionMedia.removeEventListener('change', motionHandler);
|
|
20946
|
+
};
|
|
20947
|
+
}
|
|
20948
|
+
};
|
|
20949
|
+
const setupKeyboardDetection = () => {
|
|
20950
|
+
if (typeof document === 'undefined') return;
|
|
20951
|
+
let keyboardUser = false;
|
|
20952
|
+
const handleKeyDown = e => {
|
|
20953
|
+
if (e.key === 'Tab') {
|
|
20954
|
+
keyboardUser = true;
|
|
20955
|
+
dispatch({
|
|
20956
|
+
type: 'SET_KEYBOARD_USER',
|
|
20957
|
+
payload: true
|
|
20958
|
+
});
|
|
20959
|
+
document.body.classList.add('keyboard-user');
|
|
20960
|
+
}
|
|
20961
|
+
};
|
|
20962
|
+
const handleMouseDown = () => {
|
|
20963
|
+
if (keyboardUser) {
|
|
20964
|
+
keyboardUser = false;
|
|
20965
|
+
dispatch({
|
|
20966
|
+
type: 'SET_KEYBOARD_USER',
|
|
20967
|
+
payload: false
|
|
20968
|
+
});
|
|
20969
|
+
document.body.classList.remove('keyboard-user');
|
|
20970
|
+
}
|
|
20971
|
+
};
|
|
20972
|
+
document.addEventListener('keydown', handleKeyDown);
|
|
20973
|
+
document.addEventListener('mousedown', handleMouseDown);
|
|
20974
|
+
return () => {
|
|
20975
|
+
document.removeEventListener('keydown', handleKeyDown);
|
|
20976
|
+
document.removeEventListener('mousedown', handleMouseDown);
|
|
20977
|
+
};
|
|
20978
|
+
};
|
|
20979
|
+
const initializeFocusManagement = () => {
|
|
20980
|
+
if (typeof document === 'undefined') return;
|
|
20981
|
+
// Enhanced focus indicators for keyboard users
|
|
20982
|
+
const style = document.createElement('style');
|
|
20983
|
+
style.textContent = `
|
|
20984
|
+
.keyboard-user *:focus {
|
|
20985
|
+
outline: 3px solid #005cee !important;
|
|
20986
|
+
outline-offset: 2px !important;
|
|
20987
|
+
}
|
|
20988
|
+
|
|
20989
|
+
.high-contrast *:focus {
|
|
20990
|
+
outline: 3px solid #ffffff !important;
|
|
20991
|
+
outline-offset: 2px !important;
|
|
20992
|
+
box-shadow: 0 0 0 1px #000000 !important;
|
|
20993
|
+
}
|
|
20994
|
+
|
|
20995
|
+
.reduced-motion * {
|
|
20996
|
+
animation-duration: 0.01ms !important;
|
|
20997
|
+
animation-iteration-count: 1 !important;
|
|
20998
|
+
transition-duration: 0.01ms !important;
|
|
20999
|
+
}
|
|
21000
|
+
|
|
21001
|
+
.large-text {
|
|
21002
|
+
font-size: 1.2em !important;
|
|
21003
|
+
}
|
|
21004
|
+
`;
|
|
21005
|
+
document.head.appendChild(style);
|
|
21006
|
+
};
|
|
21007
|
+
const runAccessibilityAudit = () => {
|
|
21008
|
+
if (typeof document === 'undefined') return;
|
|
21009
|
+
setTimeout(() => {
|
|
21010
|
+
const issues = [];
|
|
21011
|
+
// Check for images without alt text
|
|
21012
|
+
const images = document.querySelectorAll('img:not([alt])');
|
|
21013
|
+
images.forEach(img => {
|
|
21014
|
+
issues.push({
|
|
21015
|
+
type: 'missing-alt-text',
|
|
21016
|
+
message: 'Image missing alt attribute',
|
|
21017
|
+
level: 'error',
|
|
21018
|
+
element: img
|
|
21019
|
+
});
|
|
21020
|
+
});
|
|
21021
|
+
// Check for buttons without accessible names
|
|
21022
|
+
const buttons = document.querySelectorAll('button:not([aria-label]):not([title])');
|
|
21023
|
+
buttons.forEach(button => {
|
|
21024
|
+
if (!button.textContent?.trim()) {
|
|
21025
|
+
issues.push({
|
|
21026
|
+
type: 'unnamed-button',
|
|
21027
|
+
message: 'Button missing accessible name',
|
|
21028
|
+
level: 'error',
|
|
21029
|
+
element: button
|
|
21030
|
+
});
|
|
21031
|
+
}
|
|
21032
|
+
});
|
|
21033
|
+
// Check for form inputs without labels
|
|
21034
|
+
const inputs = document.querySelectorAll('input:not([aria-label]):not([title])');
|
|
21035
|
+
inputs.forEach(input => {
|
|
21036
|
+
const id = input.getAttribute('id');
|
|
21037
|
+
if (id) {
|
|
21038
|
+
const label = document.querySelector(`label[for="${id}"]`);
|
|
21039
|
+
if (!label) {
|
|
21040
|
+
issues.push({
|
|
21041
|
+
type: 'unlabeled-input',
|
|
21042
|
+
message: 'Form input missing label',
|
|
21043
|
+
level: 'error',
|
|
21044
|
+
element: input
|
|
21045
|
+
});
|
|
21046
|
+
}
|
|
21047
|
+
} else {
|
|
21048
|
+
issues.push({
|
|
21049
|
+
type: 'unlabeled-input',
|
|
21050
|
+
message: 'Form input missing label',
|
|
21051
|
+
level: 'error',
|
|
21052
|
+
element: input
|
|
21053
|
+
});
|
|
21054
|
+
}
|
|
21055
|
+
});
|
|
21056
|
+
dispatch({
|
|
21057
|
+
type: 'CLEAR_ISSUES'
|
|
21058
|
+
});
|
|
21059
|
+
issues.forEach(issue => {
|
|
21060
|
+
dispatch({
|
|
21061
|
+
type: 'ADD_ISSUE',
|
|
21062
|
+
payload: issue
|
|
21063
|
+
});
|
|
21064
|
+
});
|
|
21065
|
+
if (issues.length > 0) {
|
|
21066
|
+
console.group('🔍 Accessibility Issues Found');
|
|
21067
|
+
issues.forEach(issue => {
|
|
21068
|
+
const logMethod = issue.level === 'error' ? console.error : console.warn;
|
|
21069
|
+
logMethod(`${issue.type}: ${issue.message}`);
|
|
21070
|
+
});
|
|
21071
|
+
console.groupEnd();
|
|
21072
|
+
}
|
|
21073
|
+
}, 1000);
|
|
21074
|
+
};
|
|
21075
|
+
// Context value
|
|
21076
|
+
const contextValue = {
|
|
21077
|
+
...state,
|
|
21078
|
+
// Actions
|
|
21079
|
+
setHighContrast: enabled => dispatch({
|
|
21080
|
+
type: 'SET_HIGH_CONTRAST',
|
|
21081
|
+
payload: enabled
|
|
21082
|
+
}),
|
|
21083
|
+
setReducedMotion: enabled => dispatch({
|
|
21084
|
+
type: 'SET_REDUCED_MOTION',
|
|
21085
|
+
payload: enabled
|
|
21086
|
+
}),
|
|
21087
|
+
setLargeText: enabled => dispatch({
|
|
21088
|
+
type: 'SET_LARGE_TEXT',
|
|
21089
|
+
payload: enabled
|
|
21090
|
+
}),
|
|
21091
|
+
setFocusVisible: enabled => dispatch({
|
|
21092
|
+
type: 'SET_FOCUS_VISIBLE',
|
|
21093
|
+
payload: enabled
|
|
21094
|
+
}),
|
|
21095
|
+
// Utilities
|
|
21096
|
+
announce: (message, level = 'polite') => {
|
|
21097
|
+
ariaLiveManager.announce(message, level);
|
|
21098
|
+
dispatch({
|
|
21099
|
+
type: 'SET_ANNOUNCEMENT',
|
|
21100
|
+
payload: {
|
|
21101
|
+
message,
|
|
21102
|
+
level,
|
|
21103
|
+
timestamp: Date.now()
|
|
21104
|
+
}
|
|
21105
|
+
});
|
|
21106
|
+
},
|
|
21107
|
+
announcePolite: message => {
|
|
21108
|
+
ariaLiveManager.announcePolite(message);
|
|
21109
|
+
dispatch({
|
|
21110
|
+
type: 'SET_ANNOUNCEMENT',
|
|
21111
|
+
payload: {
|
|
21112
|
+
message,
|
|
21113
|
+
level: 'polite',
|
|
21114
|
+
timestamp: Date.now()
|
|
21115
|
+
}
|
|
21116
|
+
});
|
|
21117
|
+
},
|
|
21118
|
+
announceAssertive: message => {
|
|
21119
|
+
ariaLiveManager.announceAssertive(message);
|
|
21120
|
+
dispatch({
|
|
21121
|
+
type: 'SET_ANNOUNCEMENT',
|
|
21122
|
+
payload: {
|
|
21123
|
+
message,
|
|
21124
|
+
level: 'assertive',
|
|
21125
|
+
timestamp: Date.now()
|
|
21126
|
+
}
|
|
21127
|
+
});
|
|
21128
|
+
},
|
|
21129
|
+
addIssue: issue => dispatch({
|
|
21130
|
+
type: 'ADD_ISSUE',
|
|
21131
|
+
payload: issue
|
|
21132
|
+
}),
|
|
21133
|
+
clearIssues: () => dispatch({
|
|
21134
|
+
type: 'CLEAR_ISSUES'
|
|
21135
|
+
}),
|
|
21136
|
+
// Audit function
|
|
21137
|
+
runAudit: runAccessibilityAudit
|
|
21138
|
+
};
|
|
21139
|
+
// Apply CSS classes based on preferences
|
|
21140
|
+
useEffect(() => {
|
|
21141
|
+
if (typeof document === 'undefined') return;
|
|
21142
|
+
const {
|
|
21143
|
+
highContrast,
|
|
21144
|
+
reducedMotion,
|
|
21145
|
+
largeText
|
|
21146
|
+
} = state;
|
|
21147
|
+
document.body.classList.toggle('high-contrast', highContrast);
|
|
21148
|
+
document.body.classList.toggle('reduced-motion', reducedMotion);
|
|
21149
|
+
document.body.classList.toggle('large-text', largeText);
|
|
21150
|
+
}, [state.highContrast, state.reducedMotion, state.largeText]);
|
|
21151
|
+
return jsx(AccessibilityContext.Provider, {
|
|
21152
|
+
value: contextValue,
|
|
21153
|
+
children: children
|
|
21154
|
+
});
|
|
21155
|
+
};
|
|
21156
|
+
/**
|
|
21157
|
+
* Hook to access accessibility context
|
|
21158
|
+
*/
|
|
21159
|
+
const useAccessibility = () => {
|
|
21160
|
+
const context = useContext(AccessibilityContext);
|
|
21161
|
+
if (!context) {
|
|
21162
|
+
throw new Error('useAccessibility must be used within an AccessibilityProvider');
|
|
21163
|
+
}
|
|
21164
|
+
return context;
|
|
21165
|
+
};
|
|
21166
|
+
/**
|
|
21167
|
+
* Higher-Order Component for accessibility enhancements
|
|
21168
|
+
*/
|
|
21169
|
+
const withAccessibility = WrappedComponent => {
|
|
21170
|
+
const AccessibilityEnhancedComponent = props => {
|
|
21171
|
+
const accessibility = useAccessibility();
|
|
21172
|
+
return jsx(WrappedComponent, {
|
|
21173
|
+
...props,
|
|
21174
|
+
accessibility: accessibility
|
|
21175
|
+
});
|
|
21176
|
+
};
|
|
21177
|
+
AccessibilityEnhancedComponent.displayName = `withAccessibility(${WrappedComponent.displayName || WrappedComponent.name || 'Component'})`;
|
|
21178
|
+
return AccessibilityEnhancedComponent;
|
|
21179
|
+
};
|
|
21180
|
+
|
|
20582
21181
|
const QwickApp = ({
|
|
20583
21182
|
children,
|
|
20584
21183
|
className,
|
|
@@ -20640,16 +21239,20 @@ const QwickApp = ({
|
|
|
20640
21239
|
dataSource: dataSource,
|
|
20641
21240
|
children: content
|
|
20642
21241
|
}) : content;
|
|
20643
|
-
const appContent = jsx(
|
|
20644
|
-
|
|
20645
|
-
|
|
20646
|
-
|
|
20647
|
-
|
|
20648
|
-
|
|
20649
|
-
|
|
20650
|
-
|
|
20651
|
-
|
|
20652
|
-
|
|
21242
|
+
const appContent = jsx(ErrorBoundary, {
|
|
21243
|
+
children: jsx(AccessibilityProvider, {
|
|
21244
|
+
children: jsx("div", {
|
|
21245
|
+
className: `qwick-app ${className || ''}`,
|
|
21246
|
+
style: style,
|
|
21247
|
+
children: jsx(ThemeProvider, {
|
|
21248
|
+
appId: appId,
|
|
21249
|
+
defaultTheme: defaultTheme,
|
|
21250
|
+
defaultPalette: defaultPalette,
|
|
21251
|
+
children: jsx(QwickAppContext.Provider, {
|
|
21252
|
+
value: contextValue,
|
|
21253
|
+
children: wrappedContent
|
|
21254
|
+
})
|
|
21255
|
+
})
|
|
20653
21256
|
})
|
|
20654
21257
|
})
|
|
20655
21258
|
});
|
|
@@ -20757,6 +21360,186 @@ const setCSSVariable = (property, value) => {
|
|
|
20757
21360
|
document.documentElement.style.setProperty(property, value);
|
|
20758
21361
|
};
|
|
20759
21362
|
|
|
21363
|
+
/**
|
|
21364
|
+
* Generic Breadcrumbs component for navigation hierarchy
|
|
21365
|
+
*
|
|
21366
|
+
* Features:
|
|
21367
|
+
* - Accessible navigation with proper ARIA labels
|
|
21368
|
+
* - Customizable separators and icons
|
|
21369
|
+
* - Responsive design with item truncation
|
|
21370
|
+
* - Support for custom navigation handlers
|
|
21371
|
+
* - Keyboard navigation support
|
|
21372
|
+
* - Screen reader friendly
|
|
21373
|
+
*/
|
|
21374
|
+
const Breadcrumbs = ({
|
|
21375
|
+
items,
|
|
21376
|
+
separator = '/',
|
|
21377
|
+
className = '',
|
|
21378
|
+
onNavigate,
|
|
21379
|
+
maxItems,
|
|
21380
|
+
showRoot = true
|
|
21381
|
+
}) => {
|
|
21382
|
+
// Filter and prepare items
|
|
21383
|
+
let displayItems = showRoot ? items : items.slice(1);
|
|
21384
|
+
// Handle max items with ellipsis
|
|
21385
|
+
if (maxItems && displayItems.length > maxItems) {
|
|
21386
|
+
const firstItems = displayItems.slice(0, 1);
|
|
21387
|
+
const lastItems = displayItems.slice(-Math.max(1, maxItems - 2));
|
|
21388
|
+
displayItems = [...firstItems, {
|
|
21389
|
+
label: '...',
|
|
21390
|
+
href: undefined,
|
|
21391
|
+
current: false
|
|
21392
|
+
}, ...lastItems];
|
|
21393
|
+
}
|
|
21394
|
+
const handleItemClick = (e, item, index) => {
|
|
21395
|
+
if (onNavigate) {
|
|
21396
|
+
e.preventDefault();
|
|
21397
|
+
onNavigate(item, index);
|
|
21398
|
+
}
|
|
21399
|
+
};
|
|
21400
|
+
const handleKeyDown = (e, item, index) => {
|
|
21401
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
21402
|
+
e.preventDefault();
|
|
21403
|
+
if (onNavigate) {
|
|
21404
|
+
onNavigate(item, index);
|
|
21405
|
+
} else if (item.href) {
|
|
21406
|
+
window.location.href = item.href;
|
|
21407
|
+
}
|
|
21408
|
+
}
|
|
21409
|
+
};
|
|
21410
|
+
if (displayItems.length <= 1) {
|
|
21411
|
+
return null;
|
|
21412
|
+
}
|
|
21413
|
+
return jsx("nav", {
|
|
21414
|
+
className: `breadcrumbs ${className}`,
|
|
21415
|
+
role: "navigation",
|
|
21416
|
+
"aria-label": "Breadcrumb navigation",
|
|
21417
|
+
style: {
|
|
21418
|
+
display: 'flex',
|
|
21419
|
+
alignItems: 'center',
|
|
21420
|
+
fontSize: '14px',
|
|
21421
|
+
color: '#6b7280',
|
|
21422
|
+
...defaultStyles.nav
|
|
21423
|
+
},
|
|
21424
|
+
children: jsx("ol", {
|
|
21425
|
+
style: {
|
|
21426
|
+
display: 'flex',
|
|
21427
|
+
alignItems: 'center',
|
|
21428
|
+
listStyle: 'none',
|
|
21429
|
+
margin: 0,
|
|
21430
|
+
padding: 0,
|
|
21431
|
+
gap: '8px'
|
|
21432
|
+
},
|
|
21433
|
+
children: displayItems.map((item, index) => {
|
|
21434
|
+
const isLast = index === displayItems.length - 1;
|
|
21435
|
+
const isClickable = (item.href || onNavigate) && !item.current && item.label !== '...';
|
|
21436
|
+
return jsxs("li", {
|
|
21437
|
+
style: {
|
|
21438
|
+
display: 'flex',
|
|
21439
|
+
alignItems: 'center'
|
|
21440
|
+
},
|
|
21441
|
+
children: [isClickable ? jsxs("a", {
|
|
21442
|
+
href: item.href,
|
|
21443
|
+
onClick: e => handleItemClick(e, item, index),
|
|
21444
|
+
onKeyDown: e => handleKeyDown(e, item, index),
|
|
21445
|
+
style: {
|
|
21446
|
+
...defaultStyles.link,
|
|
21447
|
+
color: isLast ? '#374151' : '#6b7280',
|
|
21448
|
+
textDecoration: 'none',
|
|
21449
|
+
display: 'flex',
|
|
21450
|
+
alignItems: 'center',
|
|
21451
|
+
gap: '4px'
|
|
21452
|
+
},
|
|
21453
|
+
tabIndex: 0,
|
|
21454
|
+
"aria-current": item.current ? 'page' : undefined,
|
|
21455
|
+
children: [item.icon && jsx("span", {
|
|
21456
|
+
style: {
|
|
21457
|
+
display: 'flex',
|
|
21458
|
+
alignItems: 'center'
|
|
21459
|
+
},
|
|
21460
|
+
"aria-hidden": "true",
|
|
21461
|
+
children: item.icon
|
|
21462
|
+
}), jsx("span", {
|
|
21463
|
+
children: item.label
|
|
21464
|
+
})]
|
|
21465
|
+
}) : jsxs("span", {
|
|
21466
|
+
style: {
|
|
21467
|
+
...defaultStyles.current,
|
|
21468
|
+
color: isLast ? '#111827' : '#6b7280',
|
|
21469
|
+
fontWeight: isLast ? 600 : 400,
|
|
21470
|
+
display: 'flex',
|
|
21471
|
+
alignItems: 'center',
|
|
21472
|
+
gap: '4px'
|
|
21473
|
+
},
|
|
21474
|
+
"aria-current": item.current ? 'page' : undefined,
|
|
21475
|
+
children: [item.icon && jsx("span", {
|
|
21476
|
+
style: {
|
|
21477
|
+
display: 'flex',
|
|
21478
|
+
alignItems: 'center'
|
|
21479
|
+
},
|
|
21480
|
+
"aria-hidden": "true",
|
|
21481
|
+
children: item.icon
|
|
21482
|
+
}), jsx("span", {
|
|
21483
|
+
children: item.label
|
|
21484
|
+
})]
|
|
21485
|
+
}), !isLast && jsx("span", {
|
|
21486
|
+
style: {
|
|
21487
|
+
display: 'flex',
|
|
21488
|
+
alignItems: 'center',
|
|
21489
|
+
marginLeft: '8px',
|
|
21490
|
+
color: '#d1d5db',
|
|
21491
|
+
fontSize: '12px'
|
|
21492
|
+
},
|
|
21493
|
+
"aria-hidden": "true",
|
|
21494
|
+
children: separator
|
|
21495
|
+
})]
|
|
21496
|
+
}, `${item.label}-${index}`);
|
|
21497
|
+
})
|
|
21498
|
+
})
|
|
21499
|
+
});
|
|
21500
|
+
};
|
|
21501
|
+
// Default styles
|
|
21502
|
+
const defaultStyles = {
|
|
21503
|
+
nav: {
|
|
21504
|
+
padding: '8px 0'
|
|
21505
|
+
},
|
|
21506
|
+
link: {
|
|
21507
|
+
transition: 'color 0.2s ease',
|
|
21508
|
+
cursor: 'pointer',
|
|
21509
|
+
borderRadius: '4px',
|
|
21510
|
+
padding: '4px',
|
|
21511
|
+
margin: '-4px'
|
|
21512
|
+
},
|
|
21513
|
+
current: {
|
|
21514
|
+
padding: '4px'
|
|
21515
|
+
}
|
|
21516
|
+
};
|
|
21517
|
+
/**
|
|
21518
|
+
* Hook for managing breadcrumb state
|
|
21519
|
+
*/
|
|
21520
|
+
const useBreadcrumbs = () => {
|
|
21521
|
+
const [breadcrumbs, setBreadcrumbs] = React.useState([]);
|
|
21522
|
+
const addBreadcrumb = React.useCallback(item => {
|
|
21523
|
+
setBreadcrumbs(prev => [...prev, item]);
|
|
21524
|
+
}, []);
|
|
21525
|
+
const removeBreadcrumb = React.useCallback(index => {
|
|
21526
|
+
setBreadcrumbs(prev => prev.filter((_, i) => i !== index));
|
|
21527
|
+
}, []);
|
|
21528
|
+
const setBreadcrumbsCurrent = React.useCallback(items => {
|
|
21529
|
+
setBreadcrumbs(items);
|
|
21530
|
+
}, []);
|
|
21531
|
+
const clearBreadcrumbs = React.useCallback(() => {
|
|
21532
|
+
setBreadcrumbs([]);
|
|
21533
|
+
}, []);
|
|
21534
|
+
return {
|
|
21535
|
+
breadcrumbs,
|
|
21536
|
+
addBreadcrumb,
|
|
21537
|
+
removeBreadcrumb,
|
|
21538
|
+
setBreadcrumbs: setBreadcrumbsCurrent,
|
|
21539
|
+
clearBreadcrumbs
|
|
21540
|
+
};
|
|
21541
|
+
};
|
|
21542
|
+
|
|
20760
21543
|
const QwickAppsLogo = props => {
|
|
20761
21544
|
const {
|
|
20762
21545
|
styleProps,
|
|
@@ -24223,4 +25006,4 @@ var ActionType;
|
|
|
24223
25006
|
ActionType["CANCEL"] = "cancel";
|
|
24224
25007
|
})(ActionType || (ActionType = {}));
|
|
24225
25008
|
|
|
24226
|
-
export { AVAILABLE_PALETTES, ActionModel, ActionType, AllPalettes, Article, ArticleModel, BasePage, Button, CardListGrid, CardListGridModel, ChoiceInputField, ChoiceInputFieldModel, Code, CodeModel, Content, ContentModel, CoverImageHeader, CoverImageHeaderModel, DataProvider, DataProxy, DimensionsProvider, FeatureCard, FeatureCardActionModel, FeatureCardModel, FeatureGrid, FeatureGridModel, FeatureItemModel, Footer, FooterItemModel, FooterModel, FooterSectionModel, FormBlock, FormBlockModel, FormMethod, FormPage, GridCell, GridLayout, HeaderActionModel, HeroBlock, HeroBlockModel, Html, HtmlInputField, Logo, Markdown, MetadataItemModel, Page, PageBannerHeader, PageBannerHeaderModel, PaletteAutumn, PaletteCosmic, PaletteDefault, PaletteOcean, PaletteProvider, PaletteSpring, PaletteSwitcher, PaletteSwitcherModel, PaletteWinter, ProductCard, ProductCardActionModel, ProductCardModel, ProductModel, QWICKAPP_COMPONENT, QwickApp, QwickAppsLogo, SafeSpan, SafeSpanModel, Section, SectionModel, SelectInputField, T, TextField, TextInputField, TextInputFieldModel, ThemeProvider, ThemeSwitcher, ThemeSwitcherModel, applyCustomPalette, clearUserPalettePreference, clearUserThemePreference, createLogger, createPaletteFromCurrentTheme, deleteCustomPalette, exportPalette, getCSSVariable, getComputedTheme, getCurrentPalette, getCurrentTheme, getCustomPalettes, getPaletteConfig, getPaletteName, getSystemTheme, getThemePerformanceStats, importPalette, initializePalette, initializeTheme, loadUserPalettePreference, loadUserThemePreference, logThemePerformanceStats, loggers, resetThemePerformanceStats, resolveDimension, resolveDimensions, resolveSpacing, resolveSpacingProps, saveCustomPalette, savePalettePreference, saveThemePreference, saveUserPalettePreference, saveUserThemePreference, setCSSVariable, setPalette, setTheme, t, useBaseProps, useData, useDataBinding, useDataContext, useDataProvider, useDimensions, usePalette, useQwickApp, useResolveTemplate, useSafeLocation, useSafeNavigate, useTemplate, useTheme };
|
|
25009
|
+
export { AVAILABLE_PALETTES, AccessibilityProvider, ActionModel, ActionType, AllPalettes, Article, ArticleModel, BasePage, Breadcrumbs, Button, CardListGrid, CardListGridModel, ChoiceInputField, ChoiceInputFieldModel, Code, CodeModel, Content, ContentModel, CoverImageHeader, CoverImageHeaderModel, DataProvider, DataProxy, DimensionsProvider, ErrorBoundary, FeatureCard, FeatureCardActionModel, FeatureCardModel, FeatureGrid, FeatureGridModel, FeatureItemModel, Footer, FooterItemModel, FooterModel, FooterSectionModel, FormBlock, FormBlockModel, FormMethod, FormPage, GridCell, GridLayout, HeaderActionModel, HeroBlock, HeroBlockModel, Html, HtmlInputField, Logo, Markdown, MetadataItemModel, Page, PageBannerHeader, PageBannerHeaderModel, PaletteAutumn, PaletteCosmic, PaletteDefault, PaletteOcean, PaletteProvider, PaletteSpring, PaletteSwitcher, PaletteSwitcherModel, PaletteWinter, ProductCard, ProductCardActionModel, ProductCardModel, ProductModel, QWICKAPP_COMPONENT, QwickApp, QwickAppsLogo, SafeSpan, SafeSpanModel, Section, SectionModel, SelectInputField, T, TextField, TextInputField, TextInputFieldModel, ThemeProvider, ThemeSwitcher, ThemeSwitcherModel, applyCustomPalette, clearUserPalettePreference, clearUserThemePreference, createLogger, createPaletteFromCurrentTheme, deleteCustomPalette, exportPalette, getCSSVariable, getComputedTheme, getCurrentPalette, getCurrentTheme, getCustomPalettes, getPaletteConfig, getPaletteName, getSystemTheme, getThemePerformanceStats, importPalette, initializePalette, initializeTheme, loadUserPalettePreference, loadUserThemePreference, logThemePerformanceStats, loggers, resetThemePerformanceStats, resolveDimension, resolveDimensions, resolveSpacing, resolveSpacingProps, saveCustomPalette, savePalettePreference, saveThemePreference, saveUserPalettePreference, saveUserThemePreference, setCSSVariable, setPalette, setTheme, t, useAccessibility, useBaseProps, useBreadcrumbs, useData, useDataBinding, useDataContext, useDataProvider, useDimensions, usePalette, useQwickApp, useResolveTemplate, useSafeLocation, useSafeNavigate, useTemplate, useTheme, withAccessibility, withErrorBoundary };
|