Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve color widget picker and types #5948

Merged
merged 3 commits into from
Apr 5, 2024

Conversation

sneridagh
Copy link
Member

No description provided.

Copy link

netlify bot commented Apr 5, 2024

Deploy Preview for plone-components canceled.

Name Link
🔨 Latest commit 5161f5b
🔍 Latest deploy log https://app.netlify.com/sites/plone-components/deploys/660fd0054dfa6500089c1b4d

Copy link

netlify bot commented Apr 5, 2024

Deploy Preview for volto canceled.

Name Link
🔨 Latest commit 5161f5b
🔍 Latest deploy log https://app.netlify.com/sites/volto/deploys/660fd0054db61b0008defd7c

@sneridagh sneridagh merged commit 7eaf92a into main Apr 5, 2024
73 checks passed
@sneridagh sneridagh deleted the improveColorWidgetPickerAndTypes branch April 5, 2024 10:38
autocomplete: React.ComponentType;
color_picker: React.ComponentType;
select: React.ComponentType;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sneridagh This doesn't seem right to me. These are not interfaces with a fixed set of keys. They are mappings which can take an arbitrary number of string: React.ComponentType entries, to register new widget types. Isn't there some way we can express that in a type without needing to list all these?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The beauty of a TS interface is that you can extend them as in:

declare module '@plone/types' {
  export interface WidgetsConfigByWidget {
    BackgroundColorWidget: React.ComponentType<any>;
  }
}

anywhere, eg. in your add-on.

https://github.com/kitconcept/kitconcept.com/blob/main/frontend/src/addons/volto-kitconcept_com/src/index.ts#L50-L53

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sneridagh Yeah but it seems ridiculous if I have to update an interface just to declare that there is a new type of widget that I'd like to register, and then also actually register it.

I think these types should be declared as Record<string, React.ComponentType<any> -- https://dmitripavlutin.com/typescript-record/

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@davisagli You are right, in this one makes sense, because all have the same shape (They are all Record<string, React.ComponentType), in others is not that easy, and TS is not that smart when all the records do not have the same shape, or if you have to start writing complex unions.

I'd like also to standardize and make people know and use the extending interfaces pattern, so my reasoning path went in that way too. But it's true that as much as we can prevent people from writing code, we should.

Let me try it out how well it works and I will make a PR.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@davisagli Trying it out, I remembered why :) So it's all about autocompletion too. With a generic record you cannot have both. Also this is not allowed:

export interface WidgetsConfig = Record<WidgetsConfigKeys, React.ComponentType<any>>

And you can't do:

export interface WidgetsConfig {
  default: React.ComponentType;
  id: WidgetsConfigById;
  widget: WidgetsConfigByWidget;
  vocabulary: WidgetsConfigByVocabulary;
  factory: WidgetsConfigByFactory;
  choices: React.ComponentType;
  type: WidgetsConfigByType;
  views: WidgetsConfigViews;
  [k in string]: Record<string, React.ComponentType<any>>;
}

Since Interfaces can't declare both static and dynamic keys:

https://ts-error-translator.vercel.app/?error=IIAgtghgDlCmAmIAuBPO4IpAOwPZJHlgGMAbCAJ1hCgtzgqQEtYBnEXC8WJAC13isAdEA

Since interfaces don't work like this, so you have to fall back to types, then they are not extendable.
So we can only have both extensibility and autocompletion using this pattern.

Let's talk about this on Monday!

sneridagh added a commit that referenced this pull request Apr 16, 2024
* main: (28 commits)
  Bump vite from 5.1.5 to 5.1.7 (#5946)
  Fix pt_BR translation of invalid email message (#5953)
  Fix markup shortcuts for bold, italic and strikethough fix (#5606)
  Release 18.0.0-alpha.27
  Release @plone/types 1.0.0-alpha.10
  Improve color widget picker and types (#5948)
  Enhanced navigation reducer in Volto (#5817)
  Release 18.0.0-alpha.26
  Rename news item
  Release @plone/slate 18.0.0-alpha.11
  Release @plone/registry 1.5.5
  Release @plone/types 1.0.0-alpha.9
  docs: Cleanup obsolete EEA projects and update info about EEA main website (#5943)
  Bump vite from 5.1.4 to 5.1.5 (#5942)
  Add a new label `needs: triage` to new bug reports (#5940)
  Fix redirect of `https://sustainability.eionet.europa.eu` to `https:/… (#5941)
  Does not show borders in addon block inputs (#5898)
  Fix edge case in search options mangling when the options are false-ish (#5869)
  Add additional parameters to ContentsUploadModal to be reusable in different scenarios (#5881)
  fix(slate): fix insert/remove element edgecase bug in slate (#5926)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants