Skip to content

Commit 2b7cdfa

Browse files
committed
update example, properly propagate theme by using v-sheet
1 parent 3da5c53 commit 2b7cdfa

File tree

5 files changed

+221
-33
lines changed

5 files changed

+221
-33
lines changed

packages/jsonforms-vuetify-webcomponent/index.html

Lines changed: 191 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -35,44 +35,212 @@
3535
display: block;
3636
max-width: 100%;
3737
}
38+
39+
/* Example selector styles */
40+
.example-selector {
41+
position: fixed;
42+
bottom: 20px;
43+
left: 20px;
44+
z-index: 1000;
45+
}
46+
47+
.example-icon {
48+
width: 50px;
49+
height: 50px;
50+
background: #1976d2;
51+
border-radius: 50%;
52+
display: flex;
53+
align-items: center;
54+
justify-content: center;
55+
cursor: pointer;
56+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
57+
transition: all 0.3s ease;
58+
}
59+
60+
.example-icon:hover {
61+
background: #1565c0;
62+
transform: scale(1.05);
63+
}
64+
65+
.example-icon svg {
66+
width: 24px;
67+
height: 24px;
68+
fill: white;
69+
}
70+
71+
.example-list {
72+
position: absolute;
73+
bottom: 60px;
74+
left: 0;
75+
background: white;
76+
border-radius: 8px;
77+
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2);
78+
min-width: 200px;
79+
max-height: 300px;
80+
overflow-y: auto;
81+
display: none;
82+
}
83+
84+
.example-list.show {
85+
display: block;
86+
animation: slideUp 0.3s ease;
87+
}
88+
89+
@keyframes slideUp {
90+
from {
91+
opacity: 0;
92+
transform: translateY(10px);
93+
}
94+
to {
95+
opacity: 1;
96+
transform: translateY(0);
97+
}
98+
}
99+
100+
.example-item {
101+
padding: 12px 16px;
102+
cursor: pointer;
103+
border-bottom: 1px solid #eee;
104+
transition: background-color 0.2s ease;
105+
}
106+
107+
.example-item:hover {
108+
background-color: #f5f5f5;
109+
}
110+
111+
.example-item:last-child {
112+
border-bottom: none;
113+
}
114+
115+
.example-item-name {
116+
font-weight: 500;
117+
color: #333;
118+
}
38119
</style>
39120
</head>
40121
<body>
41-
<div id="app"></div>
42122
<!-- <script type="module" src="./dist/vuetify-json-forms.js"></script> -->
43123
<script type="module" src="./src/web-component.ts"></script>
44-
<vuetify-json-forms> </vuetify-json-forms>
124+
<vuetify-json-forms>
125+
<div class="example-selector" slot="jsonforms-footer">
126+
<div class="example-icon" id="exampleIcon">
127+
<svg viewBox="0 0 24 24">
128+
<path d="M3,6H21V8H3V6M3,11H21V13H3V11M3,16H21V18H3V16Z" />
129+
</svg>
130+
</div>
131+
<div class="example-list" id="exampleList">
132+
<!-- Examples will be populated here -->
133+
</div>
134+
</div>
135+
</vuetify-json-forms>
45136

46137
<script type="module">
47138
import { examples } from './src/examples/index.js';
48139

49-
const example = examples[0];
50-
const input = example.input;
51-
140+
let currentExampleIndex = 0;
52141
const form = document.querySelector('vuetify-json-forms');
142+
const exampleIcon = document.getElementById('exampleIcon');
143+
const exampleList = document.getElementById('exampleList');
144+
145+
// Function to load an example
146+
function loadExample(exampleIndex) {
147+
// Check if examples array exists and index is valid
148+
if (!examples || examples.length === 0) {
149+
console.warn('No examples available');
150+
return;
151+
}
152+
153+
if (exampleIndex < 0 || exampleIndex >= examples.length) {
154+
console.warn(
155+
`Invalid example index: ${exampleIndex}. Available: 0-${examples.length - 1}`,
156+
);
157+
return;
158+
}
53159

54-
// Pass props directly as JS properties
55-
if (input) {
56-
if (input.data) form.data = input.data;
57-
if (input.schema) form.schema = input.schema;
58-
if (input.uischema) form.uischema = input.uischema;
59-
if (input.uischemas) form.uischemas = input.uischemas;
60-
if (input.config) form.config = input.config;
61-
if (input.style) form.customStyle = input.style;
62-
if (input.i18n) form.translations = input.i18n;
63-
if (input.uidata) form.uidata = input.uidata;
64-
if (input.preset) form.vuetifyOptions = input.preset;
65-
66-
if (input.actions?.onChange) {
67-
form.addEventListener('change', input.actions.onChange);
160+
const example = examples[exampleIndex];
161+
if (!example) {
162+
console.warn(`Example at index ${exampleIndex} is null or undefined`);
163+
return;
68164
}
69-
if (input.actions?.onHandleAction) {
70-
form.addEventListener('handle-action', input.actions.onHandleAction);
165+
166+
const input = example?.input;
167+
168+
// Pass props directly as JS properties
169+
if (input) {
170+
form.data = input.data;
171+
form.schema = input.schema;
172+
form.uischema = input.uischema;
173+
form.uischemas = input.uischemas;
174+
form.config = input.config;
175+
form.customStyle = input.style;
176+
form.translations = input.i18n;
177+
form.uidata = input.uidata;
178+
form.vuetifyOptions = input.preset;
179+
180+
// Remove existing event listeners and add new ones
181+
form.removeEventListener('change', handleChange);
182+
form.removeEventListener('handle-action', handleAction);
183+
184+
if (input.actions?.onChange) {
185+
form.addEventListener('change', input.actions.onChange);
186+
}
187+
if (input.actions?.onHandleAction) {
188+
form.addEventListener(
189+
'handle-action',
190+
input.actions.onHandleAction,
191+
);
192+
}
71193
}
194+
195+
currentExampleIndex = exampleIndex;
196+
console.log('Selected example:', example);
72197
}
73198

74-
// Append the component to the DOM
75-
document.getElementById('app').appendChild(form);
199+
// Default event handlers
200+
function handleChange(event) {
201+
console.log('Form changed:', event);
202+
}
203+
204+
function handleAction(event) {
205+
console.log('Action handled:', event);
206+
}
207+
208+
// Populate example list
209+
function populateExampleList() {
210+
exampleList.innerHTML = '';
211+
examples.forEach((example, index) => {
212+
const item = document.createElement('div');
213+
item.className = 'example-item';
214+
item.innerHTML = `<div class="example-item-name">${example.title || `Example ${index + 1}`}</div>`;
215+
216+
item.addEventListener('click', () => {
217+
loadExample(index);
218+
exampleList.classList.remove('show');
219+
});
220+
221+
exampleList.appendChild(item);
222+
});
223+
}
224+
225+
// Toggle example list visibility
226+
exampleIcon.addEventListener('click', (e) => {
227+
e.stopPropagation();
228+
exampleList.classList.toggle('show');
229+
});
230+
231+
// Close example list when clicking outside
232+
document.addEventListener('click', (e) => {
233+
if (
234+
!exampleList.contains(e.target) &&
235+
!exampleIcon.contains(e.target)
236+
) {
237+
exampleList.classList.remove('show');
238+
}
239+
});
240+
241+
// Initialize
242+
populateExampleList();
243+
loadExample(1); // Load first example by default
76244
</script>
77245
</body>
78246
</html>

packages/jsonforms-vuetify-webcomponent/src/examples/demo/demo.schema.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
"maximum": 100
1717
}
1818
},
19-
2019
"additionalProperties": {
2120
"type": "string",
2221
"title": "Additional Properties"
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import data from './demo.data.json';
2+
import preset from './demo.preset.json';
3+
import schema from './demo.schema.json';
4+
import uischema from './demo.uischema.json';
5+
import style from './demo.style.css?inline';
6+
7+
export const input = {
8+
data: data,
9+
preset: preset,
10+
schema: schema,
11+
uischema: uischema,
12+
style: style,
13+
};
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
import { input as basic } from './basic';
2+
import { input as demo } from './demo';
23

34
export const examples = [
45
{
56
id: 'basic',
67
title: 'Basic',
78
input: basic,
89
},
10+
{
11+
id: 'demo',
12+
title: 'Demo',
13+
input: demo,
14+
},
915
];

packages/jsonforms-vuetify-webcomponent/src/web-components/VuetifyJsonForms.ce.vue

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919
<v-locale-provider :rtl="appStore.rtl" :locale="appStore.locale">
2020
<v-theme-provider :theme="theme">
2121
<v-defaults-provider :defaults="appStore.defaults">
22-
<div v-if="error !== undefined">
23-
<v-container style="height: 400px">
22+
<v-sheet>
23+
<v-container style="height: 400px" v-if="error !== undefined">
2424
<v-row
2525
class="fill-height"
2626
align-content="center"
@@ -31,14 +31,14 @@
3131
</v-col>
3232
</v-row>
3333
</v-container>
34-
</div>
3534

36-
<resolved-json-forms
37-
v-else
38-
:state="state as JsonFormsProps"
39-
:vuetify-config="vuetifyConfig"
40-
@change="onChange"
41-
></resolved-json-forms>
35+
<resolved-json-forms
36+
v-else
37+
:state="state as JsonFormsProps"
38+
:vuetify-config="vuetifyConfig"
39+
@change="onChange"
40+
></resolved-json-forms>
41+
</v-sheet>
4242
</v-defaults-provider>
4343
</v-theme-provider>
4444
</v-locale-provider>
@@ -91,6 +91,7 @@ import {
9191
VDefaultsProvider,
9292
VLocaleProvider,
9393
VRow,
94+
VSheet,
9495
VThemeProvider,
9596
} from 'vuetify/components';
9697
import { extractAndInjectFonts } from '../util/inject-fonts';
@@ -107,6 +108,7 @@ export default defineComponent({
107108
VContainer,
108109
VRow,
109110
VCol,
111+
VSheet,
110112
DynamicElement,
111113
},
112114
emits: ['change', 'handle-action'],

0 commit comments

Comments
 (0)