osuresearch / ui Goto Github PK
View Code? Open in Web Editor NEWOhio State Research UI
Home Page: https://osuresearch.github.io/ui/main
License: MIT License
Ohio State Research UI
Home Page: https://osuresearch.github.io/ui/main
License: MIT License
Uploader does not integrate well with RHF 7 - onBlur event doesn't trigger as expected.
Current workaround is to combine a controlled version with useState
with RHF's setValue
.
Something sort of like:
const [files, setFiles] = useState<UploadedFile[]>(...);
const { setValue } = useForm();
useEffect(() => {
setValue(files);
}, [files]);
Type 'FieldErrors<{ textField: string; textAreaField: string; dateField: string; numberField: number; currencyField: number; checkboxField: boolean; yesNoField: boolean; switchField: boolean; selectField: string; comboBoxField: string; lookupField: string; checkboxSetField: string[]; radioSetField: string; }>' is not assignable to type '{ [field: string]: { message: string; }; } | undefined'.
Type 'FieldErrors<{ textField: string; textAreaField: string; dateField: string; numberField: number; currencyField: number; checkboxField: boolean; yesNoField: boolean; switchField: boolean; selectField: string; comboBoxField: string; lookupField: string; checkboxSetField: string[]; radioSetField: string; }>' is not assignable to type '{ [field: string]: { message: string; }; }'.
Property 'textField' is incompatible with index signature.
Type 'FieldError' is not assignable to type '{ message: string; }'.
Types of property 'message' are incompatible.
Type 'string | undefined' is not assignable to type 'string'.
Type 'undefined' is not assignable to type 'string'.ts(2322)
FormErrors.tsx(11, 3): The expected type comes from property 'errorMessages' which is declared here on type 'IntrinsicAttributes & StyleSystemProps & { errorMessages?: { [field: string]: { message: string; }; } | undefined; children?: ReactNode; } & RefAttributes<...>'
A number of form components don't play well with FormData
serialization, since I focused on typing and event handling for React Hook Forms.
Specifically, the YesNoField, RadioSetField, and CheckboxField aren't actually making their values available for FormData. I'm also noticing that programmatic changes to the underlying inputs (via my a11y tools) won't actually update component values. So there's a number of issues that need to be further investigated.
Currently using string '1' and '0' but this isn't intended behaviour - it's just a workaround due to the inputs only allowing strings.
Really value
, defaultValue
, and onChange
all need to work with boolean|undefined
as a yes/no is essentially a 3 state boolean switch.
Discussion of a new consistent modal API to cover:
Below are several options for APIs.
Each usage must define a state to link a modal to a trigger.
const [open, setOpen] = useState(false);
(
// Your trigger
<Button onPress={() => setOpen(true)}>Open modal</Button>
// Your modal contents
<Modal open={open} onClose={() => setOpen(false)}>
<InformationDialog />
</Modal>
)
Positives:
Negatives:
const [open, setOpen] = useState(false);
(
// Your trigger
<Button
onPress={() => setOpen(true)}
aria-expanded={open}
aria-controls={open ? 'my-unique-id' ? undefined}
>Open modal</Button>
// Your modal contents
<Modal id="my-unique-id" open={open} onClose={() => setOpen(false)}>
<InformationDialog aria-labeledby="my-unique-id" />
</Modal>
)
Note: any implementation should still allow experienced developers to break out of common usage and have a controlled modal, as long as the requirements for compliance are very clear.
Alternative of the previous example where a ref is required to associate trigger to modal.
const [open, setOpen] = useState(false);
const ref = useRef<Button>(null);
(
// Your trigger
<Button
ref={ref}
onPress={() => setOpen(true)}
>Open modal</Button>
// Your modal
<Modal triggerRef={ref} open={open} onClose={() => setOpen(false)}>
<InformationDialog />
</Modal>
)
Positives:
Negatives:
The modal trigger may only be a button of type ModalTriggerButton
and the children of that button is the dialog content.
<ModalTriggerButton label="Open modal">
{(close) => (
<InformationDialog onClose={close} />
)}
</ModalTriggerButton>
Positives:
Negatives:
The modal is a host component for content slots.
<ModalHost>
<Slot name="trigger">
<Button>Open modal</Button>
</Slot>
<Slot name="dialog">
<InformationDialog />
</Slot>
</ModalHost>
// OR - the subcomponents-style API.
// Architecturally - they're the same:
<Modal>
<Modal.Trigger>
<Button>Open modal</Button>
</Modal.Trigger>
<Modal.Dialog name="dialog">
<InformationDialog />
</Modal.Dialog>
</Modal>
Positives:
Negatives:
<Item>
children, e.g. lists and checkbox sets.Modal host acts as a functional linkage and the element to trigger the modal (button or whatever) is a render prop.
<ModalHost trigger={<Button>Open modal</Button>}>
<InformationDialog />
</ModalHost>
Positives:
Negatives:
Inverse of the prior example, the host wraps the trigger and the modal acts as the render prop:
<ModalHost modal={<InformationDialog />}>
<Button>Open modal</Button>
</ModalHost>
Positives:
Negatives:
<ModalHost modal={
<InformationDialog title="Terms of service">
Long content would go here
</InformationDialog>
}>
<Button>Open modal</Button>
</ModalHost>
// vs
function TermsOfServiceDialog() {
return (
<InformationDialog title="Terms of service">
Long content would go here
</InformationDialog>
)
}
<ModalHost modal={<TermsOfServiceDialog />}>
<Button>Open modal</Button>
</ModalHost>
// vs the inverse example where trigger is the render prop:
<ModalHost trigger={<Button>Open modal</Button>}>
<InformationDialog title="Terms of service">
Long content would go here
</InformationDialog>
</ModalHost>
Need to be able to disable the entire menu button rather than just individual items.
NumberField seems to require the locale="en-US"
prop. Make it an optional and default to US, which covers our 99.9% use case.
I love the way GraphiQL uses hlsa as the standard for their CSS variables - this lets them blend colors and control alpha a lot more easily, and possibly do some automatic-contrasting.
E.g.:
body:not(.graphql-light) .graphiql-container {
--color-primary: 338, 100%, 67%;
--color-secondary: 243, 100%, 77%;
}
.cm-s-graphiql {
color: hsla(var(--color-neutral),var(--alpha-tertiary));
}
Think about whether or not we can benefit from a design choice like this earlier on. I think it'd honestly make it easier to generate secondary palette colors for sure.
Wrapping an Electron app with <RUIProvider>
does not load the user-preferred color scheme. Doing it manually does work, however:
export default function App() {
const prefersColorScheme = window.matchMedia('(prefers-color-scheme: dark)');
return (
<RUIProvider theme={prefersColorScheme?.matches ? 'dark' : 'light'}>
<ThemeProvider theme={{}}>
<Router>
<Routes>
...
</Routes>
</Router>
</ThemeProvider>
</RUIProvider>
);
}
Pointer is still being rendered on disabled tab panels. Noticed under Safari, but I'm sure it's everywhere.
RHF 7 should be a suggestion / peer for use with RHF-related hooks, not a hard dependency. This breaks integration with our legacy applications that use RHF 6 where I'd like to sideload RUI 5 for gradual upgrade alongside ORIS/ui 4.
Add a component for admonitions that aren't alerts from an a11y point of view. Make alerts behave as actual alerts and direct developers to use admonitions for content that needs to be visually separated but not aggressive (e.g. hints and tips, additional help content, etc)
The navbar/heading component for OSU needs to be able to target a specific ID rather than a hardcoded value for the skip link.
Use case:
4.x doesn't have a default export for the new hook useRESTFileUploader, and there's no default export for the new Upload component.
So that its currency formatting would submit something like "currencyField": "1000"
instead of "currencyField": "$1000.00"
in FormData
Interesting idea I saw some other libraries that would make sense here as well:
A TypographyProvider (or TypographyScope, or similar) component could be used to apply type rules to standard DOM. So instead of having to use <Text>
and <Heading>
components for style, native <p>
and <h1>
will render using our typography rules within children of a provider.
Use cases:
Non-comprehensive list of native elements that would be styled with the provider:
h1-h5, p, em, strong, a, ul, ol, li, hr, table (and related)
Looks like I can't interact with anything on the page on Safari, fine on Firefox.
https://osuresearch.github.io/ui/?path=/docs/internal-underlay--underlay
This is still pending a fix for rendering those fonts on Windows. Once that's done, I can point to wherever the CDN is for those.
I'm stripping out the diff field support from the base UI framework and moving it into Ripple as a feature instead. While diffing is a pretty nice unique feature of RUI, I'm not seeing a case for anyone using it outside of what Ripple needs to do and it just overcomplicates this library. If there is such a case, I can backport what I do into here.
Ideally, diffing can be better implemented as a layer wrapping fields and showing two side by side to better handle cases like entire field types changing, or adding/removing options from radio sets - that's why it doesn't quite work well as a built-in feature of components.
sass
is a dev dependency for v4 because we previously were specifying sass as a dependency for app templates themselves. This is causing some havoc with recent old app migrations due to node-sass -> sass upgrades needing to happen.
Throw sass
as an actual dependency - because it is, we don't distribute compiled .css for v4 - along with anything else that needs to be more explicit.
When trying to use any component that depends on the React Stately items as collection children (RadioSetField, SelectField, CheckboxSetField) nothing is rendered:
I've tested array mapping, items
prop, and just setting explicit Item children as we have in the storybook docs:
<SelectField label="Select field">
<Item key="dx11">DirectX 11</Item>
<Item key="dx12">DirectX 12</Item>
<Item key="ogles">OpenGL ES</Item>
<Item key="ogl3">OpenGL 3.0</Item>
<Item key="metal">Metal</Item>
<Item key="vulkan">Vulkan</Item>
</SelectField>
Too many issues patched in one go, it seems:
https://github.com/osuresearch/ui/actions/runs/4050766272/jobs/6968463557
Didn't kill the NPM or Storybook release, but it count as a failure. I think semantic-release has a back-off feature of some sort? Need to dig around.
Brand footer may be combined with other elements in a semantic <footer>
, thus making it not appropriate to use the footer element itself.
Key features to touch on:
React Aria already has a progress bar hook so drive it off of that.
I like Fluent UI's lightweight progress bar. Maybe something like that:
https://developer.microsoft.com/en-us/fluentui#/controls/web/progressindicator
Use cases:
I don't like the design of their timeline at all - might be good for a marketing site but not a data-driven application.
Few references I like:
Age old Firefox bug apparently:
https://stackoverflow.com/questions/46746887/textarea-extra-row-in-firefox-browser
Trying to integrate RUI 5 components with Docusaurus results in some interesting results due to our aggressive TailwindCSS reset.
How docs originally look (out of the box classic theme):
With the RUI styles imported:
I'm not against making a whole Docusaurus theme with RUI - but it'd be nice if we could also embed and have things play nicely together since this will be a future problem with other products.
I know some libraries (Mantine?) have a setting of some sort that allows you to specify whether or not resets are applied. Or we apply resets specifically to the RUIProvider scope and touch nothing outside of there.
GraphiQL uses the "just apply within the container" approach as well for resets. E.g.:
.graphiql-container * {
box-sizing: border-box
}
LookupField is submitting the value in the input field. This needs to instead associate the Item.key
to the field on submit.
Use cases:
For situations where someone wants the text value to equate the submitted value, they should use a ComboBoxField.
Should be able to set a non-explicit theme that falls back to user's prefers-color-scheme
.
Related to #52
Example:
https://osuresearch.github.io/ui/docs/iframe.html?args=&id=layout-grid--responsive&viewMode=story
Stretch it out to full width - it ends up using the sm
style instead of the md
.
Clicking on the button doesn't clear the form
Currently, YesNoField wouldn't submit a value when a form is onSubmit
Want a pencil icon for editable fields that don't expose editor controls until clicked.
Use cases:
Using Next.js for SSR causes the Grid
component with responsive styles to not update accordingly after initial paint.
Anything that is resolving on / depending on layout responsiveness needs to update after mount from SSR.
Reloading an app on Next.js crashes on the navbar with:
`Error: Hydration failed because the initial UI does not match what was rendered on the server.
Warning: Expected server HTML to contain a matching text node for "BuckeyeLink" in <a>.
See more info here: https://nextjs.org/docs/messages/react-hydration-error
I'm using native a
tags for the navbar instead of our links (like OhioStateFooter
) so that'll most likely need to be migrated over so we have proper SSR support.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.