mirror of
https://github.com/utopia-os/utopia-ui.git
synced 2025-12-13 07:46:10 +00:00
feat(source): lazy loading (#229)
* optimized build for lazy loading * 3.0.95 * loading map overlay component * 3.0.96 * loading screen for dynamic imports * replace RichTextEditor with TextAreaInput (dummy) * reduce changeset --------- Co-authored-by: Anton Tranelis <mail@antontranelis.de>
This commit is contained in:
parent
c82084576a
commit
5dd0191d79
4
package-lock.json
generated
4
package-lock.json
generated
@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "utopia-ui",
|
"name": "utopia-ui",
|
||||||
"version": "3.0.93",
|
"version": "3.0.96",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "utopia-ui",
|
"name": "utopia-ui",
|
||||||
"version": "3.0.93",
|
"version": "3.0.96",
|
||||||
"license": "GPL-3.0-only",
|
"license": "GPL-3.0-only",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@heroicons/react": "^2.0.17",
|
"@heroicons/react": "^2.0.17",
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "utopia-ui",
|
"name": "utopia-ui",
|
||||||
"version": "3.0.93",
|
"version": "3.0.96",
|
||||||
"description": "Reuseable React Components to build mapping apps for real life communities and networks",
|
"description": "Reuseable React Components to build mapping apps for real life communities and networks",
|
||||||
"repository": "https://github.com/utopia-os/utopia-ui",
|
"repository": "https://github.com/utopia-os/utopia-ui",
|
||||||
"homepage": "https://utopia-os.org/",
|
"homepage": "https://utopia-os.org/",
|
||||||
@ -12,6 +12,11 @@
|
|||||||
"types": "./dist/index.d.ts",
|
"types": "./dist/index.d.ts",
|
||||||
"import": "./dist/index.esm.js",
|
"import": "./dist/index.esm.js",
|
||||||
"require": "./dist/index.cjs"
|
"require": "./dist/index.cjs"
|
||||||
|
},
|
||||||
|
"./Profile": {
|
||||||
|
"types": "./dist/Profile.d.ts",
|
||||||
|
"import": "./dist/Profile.esm.js",
|
||||||
|
"require": "./dist/Profile.cjs.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
@ -17,17 +17,22 @@ const aliasConfig = alias({
|
|||||||
|
|
||||||
export default [
|
export default [
|
||||||
{
|
{
|
||||||
input: 'src/index.tsx',
|
input: {
|
||||||
|
index: 'src/index.tsx',
|
||||||
|
Profile: 'src/Components/Profile/index.tsx',
|
||||||
|
},
|
||||||
output: [
|
output: [
|
||||||
{
|
{
|
||||||
file: 'dist/index.esm.js',
|
dir: 'dist/',
|
||||||
format: 'esm',
|
format: 'esm',
|
||||||
sourcemap: true,
|
sourcemap: true,
|
||||||
|
entryFileNames: '[name].esm.js',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
file: 'dist/index.cjs',
|
dir: 'dist/',
|
||||||
format: 'cjs',
|
format: 'cjs',
|
||||||
sourcemap: true,
|
sourcemap: true,
|
||||||
|
entryFileNames: '[name].cjs.js',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
plugins: [
|
plugins: [
|
||||||
@ -78,8 +83,15 @@ export default [
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: 'dist/types/src/index.d.ts',
|
input: {
|
||||||
output: [{ file: 'dist/index.d.ts', format: 'es' }],
|
index: path.resolve(__dirname, 'dist/types/src/index.d.ts'),
|
||||||
|
Profile: path.resolve(__dirname, 'dist/types/src/Components/Profile/index.d.ts'),
|
||||||
|
},
|
||||||
|
output: {
|
||||||
|
dir: path.resolve(__dirname, 'dist'),
|
||||||
|
format: 'es',
|
||||||
|
entryFileNames: '[name].d.ts',
|
||||||
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
aliasConfig,
|
aliasConfig,
|
||||||
dts({
|
dts({
|
||||||
@ -88,7 +100,7 @@ export default [
|
|||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
external: [/\.css$/], //, /\.d\.ts$/
|
external: [/\.css$/],
|
||||||
watch: false,
|
watch: false,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|||||||
65
src/Components/Input/RichTextEditor.tsx
Normal file
65
src/Components/Input/RichTextEditor.tsx
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
import { useEffect, useRef, useState } from 'react'
|
||||||
|
|
||||||
|
interface TextAreaProps {
|
||||||
|
labelTitle?: string
|
||||||
|
labelStyle?: string
|
||||||
|
containerStyle?: string
|
||||||
|
dataField?: string
|
||||||
|
inputStyle?: string
|
||||||
|
defaultValue: string
|
||||||
|
placeholder?: string
|
||||||
|
required?: boolean
|
||||||
|
size?: string
|
||||||
|
updateFormValue?: (value: string) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @category Input
|
||||||
|
*/
|
||||||
|
export function RichTextEditor({
|
||||||
|
labelTitle,
|
||||||
|
dataField,
|
||||||
|
labelStyle,
|
||||||
|
containerStyle,
|
||||||
|
inputStyle,
|
||||||
|
defaultValue,
|
||||||
|
placeholder,
|
||||||
|
required = true,
|
||||||
|
updateFormValue,
|
||||||
|
}: TextAreaProps) {
|
||||||
|
const ref = useRef<HTMLTextAreaElement>(null)
|
||||||
|
const [inputValue, setInputValue] = useState<string>(defaultValue)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setInputValue(defaultValue)
|
||||||
|
}, [defaultValue])
|
||||||
|
|
||||||
|
const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
|
||||||
|
const newValue = e.target.value
|
||||||
|
setInputValue(newValue)
|
||||||
|
if (updateFormValue) {
|
||||||
|
updateFormValue(newValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={`tw:form-control tw:w-full ${containerStyle ?? ''}`}>
|
||||||
|
{labelTitle ? (
|
||||||
|
<label className='tw:label'>
|
||||||
|
<span className={`tw:label-text tw:text-base-content ${labelStyle ?? ''}`}>
|
||||||
|
{labelTitle}
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
) : null}
|
||||||
|
<textarea
|
||||||
|
required={required}
|
||||||
|
ref={ref}
|
||||||
|
value={inputValue}
|
||||||
|
name={dataField}
|
||||||
|
className={`tw:textarea tw:textarea-bordered tw:w-full tw:leading-5 ${inputStyle ?? ''}`}
|
||||||
|
placeholder={placeholder ?? ''}
|
||||||
|
onChange={handleChange}
|
||||||
|
></textarea>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@ -4,7 +4,7 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
|
|
||||||
import { TextAreaInput } from '#components/Input'
|
import { RichTextEditor } from '#components/Input/RichTextEditor'
|
||||||
|
|
||||||
import { MarkdownHint } from './MarkdownHint'
|
import { MarkdownHint } from './MarkdownHint'
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ export const ProfileTextForm = ({
|
|||||||
</label>
|
</label>
|
||||||
<MarkdownHint />
|
<MarkdownHint />
|
||||||
</div>
|
</div>
|
||||||
<TextAreaInput
|
<RichTextEditor
|
||||||
placeholder={'...'}
|
placeholder={'...'}
|
||||||
// eslint-disable-next-line security/detect-object-injection
|
// eslint-disable-next-line security/detect-object-injection
|
||||||
defaultValue={state[field]}
|
defaultValue={state[field]}
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
import { useCallback, useEffect, useState } from 'react'
|
import { useCallback, useEffect, useState } from 'react'
|
||||||
import { useNavigate } from 'react-router-dom'
|
import { useNavigate } from 'react-router-dom'
|
||||||
|
|
||||||
import { TextAreaInput } from '#components/Input'
|
import { RichTextEditor } from '#components/Input/RichTextEditor'
|
||||||
import { useUpdateItem } from '#components/Map/hooks/useItems'
|
import { useUpdateItem } from '#components/Map/hooks/useItems'
|
||||||
import { PopupStartEndInput, TextView } from '#components/Map/Subcomponents/ItemPopupComponents'
|
import { PopupStartEndInput, TextView } from '#components/Map/Subcomponents/ItemPopupComponents'
|
||||||
import { ActionButton } from '#components/Profile/Subcomponents/ActionsButton'
|
import { ActionButton } from '#components/Profile/Subcomponents/ActionsButton'
|
||||||
@ -90,7 +90,8 @@ export const TabsForm = ({
|
|||||||
></PopupStartEndInput>
|
></PopupStartEndInput>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<TextAreaInput
|
<RichTextEditor
|
||||||
|
labelTitle='About me'
|
||||||
placeholder='about ...'
|
placeholder='about ...'
|
||||||
defaultValue={item?.text ? item.text : ''}
|
defaultValue={item?.text ? item.text : ''}
|
||||||
updateFormValue={(v) =>
|
updateFormValue={(v) =>
|
||||||
@ -102,7 +103,8 @@ export const TabsForm = ({
|
|||||||
containerStyle='tw:grow'
|
containerStyle='tw:grow'
|
||||||
inputStyle={`tw:h-full ${!item.layer.itemType.show_start_end_input && 'tw:border-t-0 tw:rounded-tl-none'}`}
|
inputStyle={`tw:h-full ${!item.layer.itemType.show_start_end_input && 'tw:border-t-0 tw:rounded-tl-none'}`}
|
||||||
/>
|
/>
|
||||||
<TextAreaInput
|
<RichTextEditor
|
||||||
|
labelTitle='Contact Info'
|
||||||
placeholder='contact info ...'
|
placeholder='contact info ...'
|
||||||
defaultValue={state.contact || ''}
|
defaultValue={state.contact || ''}
|
||||||
updateFormValue={(c) =>
|
updateFormValue={(c) =>
|
||||||
|
|||||||
11
src/Components/Templates/LoadingMapOverlay.tsx
Normal file
11
src/Components/Templates/LoadingMapOverlay.tsx
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { MapOverlayPage } from '#components/Templates/MapOverlayPage'
|
||||||
|
|
||||||
|
export const LoadingMapOverlay = () => {
|
||||||
|
return (
|
||||||
|
<MapOverlayPage backdrop className='tw:max-w-xs tw:h-64 tw:bg-transparent' card={false}>
|
||||||
|
<div className='tw:flex tw:justify-center tw:items-center tw:h-full'>
|
||||||
|
<div className='tw:loading tw:loading-spinner tw:loading-xl'></div>
|
||||||
|
</div>
|
||||||
|
</MapOverlayPage>
|
||||||
|
)
|
||||||
|
}
|
||||||
@ -45,7 +45,7 @@ export function MapOverlayPage({
|
|||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
ref={overlayRef}
|
ref={overlayRef}
|
||||||
className={`${card ? 'tw:card tw:card-body' : ''} tw:shadow-xl tw:bg-base-100 tw:p-6 ${className ?? ''} ${backdrop ? '' : 'tw:z-2000'} tw:absolute tw:top-0 tw:bottom-0 tw:right-0 tw:left-0 tw:m-auto`}
|
className={`${card ? 'tw:card tw:card-body tw:shadow-xl' : ''} tw:bg-base-100 tw:p-6 ${className ?? ''} ${backdrop ? '' : 'tw:z-2000'} tw:absolute tw:top-0 tw:bottom-0 tw:right-0 tw:left-0 tw:m-auto`}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
<button
|
<button
|
||||||
|
|||||||
@ -5,3 +5,4 @@ export { SelectUser } from './SelectUser'
|
|||||||
export { OverlayItemsIndexPage } from './OverlayItemsIndexPage'
|
export { OverlayItemsIndexPage } from './OverlayItemsIndexPage'
|
||||||
export { AttestationForm } from './AttestationForm'
|
export { AttestationForm } from './AttestationForm'
|
||||||
export { MarketView } from './MarketView'
|
export { MarketView } from './MarketView'
|
||||||
|
export { LoadingMapOverlay } from './LoadingMapOverlay'
|
||||||
|
|||||||
@ -4,7 +4,6 @@ import './css'
|
|||||||
export * from './Components/Map'
|
export * from './Components/Map'
|
||||||
export * from './Components/AppShell'
|
export * from './Components/AppShell'
|
||||||
export * from './Components/Auth'
|
export * from './Components/Auth'
|
||||||
export * from './Components/Profile'
|
|
||||||
export * from './Components/Gaming'
|
export * from './Components/Gaming'
|
||||||
export * from './Components/Templates'
|
export * from './Components/Templates'
|
||||||
export * from './Components/Input'
|
export * from './Components/Input'
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
"module": "esnext",
|
"module": "esnext",
|
||||||
"target": "ESNext",
|
"target": "ESNext",
|
||||||
"lib": ["es6", "dom","es2015", "es2016", "es2017", "es2020"],
|
"lib": ["es6", "dom","es2015", "es2016", "es2017", "es2020"],
|
||||||
"sourceMap": false,
|
"sourceMap": true,
|
||||||
"allowJs": false,
|
"allowJs": false,
|
||||||
"jsx": "react-jsx",
|
"jsx": "react-jsx",
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user