|
| 1 | +import React, { useEffect, useState } from "react"; |
| 2 | +import { IField, LanguageType, Option } from "@code-ui/docstring/dist/lib/type"; |
| 3 | +import { Docstring as DocstringView } from "@code-ui/docstring"; |
| 4 | +import { |
| 5 | + FrameworkOption, |
| 6 | + getpreset, |
| 7 | + Language, |
| 8 | + all_preset_options_map__prod, |
| 9 | + lang_by_framework, |
| 10 | + ReactOption, |
| 11 | + VanillaOption, |
| 12 | + FlutterOption, |
| 13 | + react_styles, |
| 14 | +} from "./framework-options"; |
| 15 | +import styled from "@emotion/styled"; |
| 16 | + |
| 17 | +type DesigntoCodeUserOptions = FrameworkOption; |
| 18 | + |
| 19 | +// FIXME: get useroption as props from parent. userprops & preset (optional) should be managed on its parent |
| 20 | +interface CodeOptionsControlProps { |
| 21 | + customFields?: IField[]; |
| 22 | + fallbackPreset?: string; |
| 23 | + initialPreset?: string; |
| 24 | + onUseroptionChange: (op: DesigntoCodeUserOptions) => void; |
| 25 | +} |
| 26 | + |
| 27 | +export function CodeOptionsControl(props: CodeOptionsControlProps) { |
| 28 | + const __presetname = props.initialPreset ?? props.fallbackPreset; |
| 29 | + const [presetname, setPresetname] = React.useState<string>(__presetname); |
| 30 | + const [useroption, setUseroption] = React.useState<DesigntoCodeUserOptions>( |
| 31 | + all_preset_options_map__prod[__presetname] |
| 32 | + ); |
| 33 | + |
| 34 | + // FIXME: this should be fixed on https://github.com/gridaco/code-like-ui (view CURSOR) |
| 35 | + const __dirty_sort_framework = (): Option<string>[] => { |
| 36 | + const presets = [ |
| 37 | + { |
| 38 | + name: "React", |
| 39 | + value: "react_default", |
| 40 | + description: "(default)", |
| 41 | + }, |
| 42 | + { |
| 43 | + name: "React", |
| 44 | + value: "react_with_styled_components", |
| 45 | + description: "with styled-component", |
| 46 | + }, |
| 47 | + { |
| 48 | + name: "Flutter", |
| 49 | + value: "flutter_default", |
| 50 | + description: "flutter", |
| 51 | + }, |
| 52 | + { |
| 53 | + name: "Vanilla", |
| 54 | + value: "vanilla_default", |
| 55 | + description: "vanilla Html", |
| 56 | + }, |
| 57 | + ]; |
| 58 | + |
| 59 | + /* !CURSOR! */ |
| 60 | + const sorted_plats: Option<string>[] = presets.sort((o) => { |
| 61 | + if (o.value == presetname) { |
| 62 | + return -1; |
| 63 | + } |
| 64 | + return 1; |
| 65 | + }); |
| 66 | + return sorted_plats; |
| 67 | + }; |
| 68 | + |
| 69 | + /** |
| 70 | + * actually platform preset |
| 71 | + */ |
| 72 | + const platform_field_config: IField = { |
| 73 | + tag: "@", |
| 74 | + name: "platform", // actually platform preset |
| 75 | + template: `{{ tag }}{{ name }} {{ options.name }} `, |
| 76 | + options: __dirty_sort_framework(), |
| 77 | + }; |
| 78 | + |
| 79 | + const getreactstyle = (frameworkPreset: string) => { |
| 80 | + const preset = getpreset(frameworkPreset) as ReactOption; |
| 81 | + const selected_styling = preset.styling; |
| 82 | + const sorted_langs = [ |
| 83 | + selected_styling, |
| 84 | + /* remove target item // - https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/splice */ |
| 85 | + ...react_styles.splice(1, 0, selected_styling), |
| 86 | + ]; |
| 87 | + return sorted_langs; |
| 88 | + }; |
| 89 | + |
| 90 | + const react_style_field_config: IField = { |
| 91 | + tag: "@", |
| 92 | + name: "style", // actually platform preset |
| 93 | + template: `{{ tag }}{{ name }} {{ options.name }} `, |
| 94 | + options: getreactstyle(presetname).map((l) => { |
| 95 | + return { |
| 96 | + name: l, |
| 97 | + value: l, |
| 98 | + }; |
| 99 | + }), |
| 100 | + }; |
| 101 | + |
| 102 | + const getlang = (frameworkPreset: string) => { |
| 103 | + const preset = getpreset(frameworkPreset); |
| 104 | + // if user has selected preest, get framework value by preset name, otherwise get the selected framework via `useroption` |
| 105 | + let frameowrk = preset?.framework ?? useroption.framework; |
| 106 | + |
| 107 | + const langoptions = lang_by_framework[frameowrk]; |
| 108 | + const selected_lang = preset.language; |
| 109 | + const sorted_langs = [ |
| 110 | + selected_lang, |
| 111 | + /* remove target item // - https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/splice */ |
| 112 | + ...langoptions.splice(1, 0, selected_lang), |
| 113 | + ]; |
| 114 | + return sorted_langs; |
| 115 | + }; |
| 116 | + |
| 117 | + const lang_field_config: IField = { |
| 118 | + tag: "@", |
| 119 | + name: "lang", |
| 120 | + template: `{{ tag }}{{ name }} {{ options.name }} `, |
| 121 | + options: getlang(presetname).map((l) => { |
| 122 | + return { |
| 123 | + name: l, |
| 124 | + value: l, |
| 125 | + }; |
| 126 | + }), |
| 127 | + }; |
| 128 | + |
| 129 | + const fields_config = { |
| 130 | + react: [platform_field_config, lang_field_config, react_style_field_config], |
| 131 | + flutter: [platform_field_config, lang_field_config], |
| 132 | + vanilla: [platform_field_config, lang_field_config], |
| 133 | + }; |
| 134 | + |
| 135 | + function onChagne(field: string, value: string) { |
| 136 | + // console.log("code-screen-control::onChagne", field, value); |
| 137 | + // platform here stands for platform preset |
| 138 | + if (field === "platform") { |
| 139 | + const preset = getpreset(value); |
| 140 | + setPresetname(value); |
| 141 | + setUseroption({ ...preset }); |
| 142 | + props.onUseroptionChange({ ...preset }); |
| 143 | + } else if (field === "lang") { |
| 144 | + let op: FrameworkOption; |
| 145 | + switch (value) { |
| 146 | + case "tsx": |
| 147 | + case "jsx": |
| 148 | + op = { |
| 149 | + ...useroption, |
| 150 | + language: value, // TODO: add generic type checker |
| 151 | + } as ReactOption; |
| 152 | + setUseroption(op); // FIXME: state from p |
| 153 | + props.onUseroptionChange(op); |
| 154 | + break; |
| 155 | + |
| 156 | + case "dart": |
| 157 | + op = { |
| 158 | + ...useroption, |
| 159 | + language: Language.dart, |
| 160 | + } as FlutterOption; |
| 161 | + setUseroption(op); // FIXME: state from p |
| 162 | + props.onUseroptionChange(op); |
| 163 | + break; |
| 164 | + case "html": |
| 165 | + op = { |
| 166 | + ...useroption, |
| 167 | + language: Language.html, |
| 168 | + } as VanillaOption; |
| 169 | + setUseroption(op); // FIXME: state from p |
| 170 | + props.onUseroptionChange(op); |
| 171 | + break; |
| 172 | + default: |
| 173 | + throw `This lang (${value}) is not currently supported.`; |
| 174 | + } |
| 175 | + } |
| 176 | + } |
| 177 | + |
| 178 | + const _controls = [ |
| 179 | + ...(props.customFields ?? []), |
| 180 | + ...fields_config[useroption.framework], |
| 181 | + ]; |
| 182 | + |
| 183 | + // console.log("code-screen-control::useroption", useroption); |
| 184 | + return ( |
| 185 | + <Wrapper> |
| 186 | + <DocstringView |
| 187 | + key={JSON.stringify(useroption)} |
| 188 | + lang={__lang_to_docstring_lang(useroption.language)} |
| 189 | + theme={"monokai"} |
| 190 | + padding={"16px"} |
| 191 | + controls={_controls} |
| 192 | + expandableConfig={{ |
| 193 | + lines: 2, |
| 194 | + expandable: true, |
| 195 | + hidable: true, |
| 196 | + }} |
| 197 | + onChange={onChagne} |
| 198 | + /> |
| 199 | + </Wrapper> |
| 200 | + ); |
| 201 | +} |
| 202 | + |
| 203 | +function __lang_to_docstring_lang(lang: Language): LanguageType { |
| 204 | + switch (lang) { |
| 205 | + case Language.dart: |
| 206 | + return "dart"; |
| 207 | + case Language.jsx: |
| 208 | + case Language.tsx: |
| 209 | + return "js"; |
| 210 | + } |
| 211 | +} |
| 212 | + |
| 213 | +const Wrapper = styled.div` |
| 214 | + div, |
| 215 | + ul { |
| 216 | + font-family: "Source Code Pro", "Courier New", "Lucida Console", Monaco; |
| 217 | + } |
| 218 | +`; |
0 commit comments