-
Notifications
You must be signed in to change notification settings - Fork 10
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
Feature: Locale Provider #434
Conversation
✔️ Deploy Preview for ingred-ui ready! 🔨 Explore the source changes: 215ac11 🔍 Inspect the deploy log: https://app.netlify.com/sites/ingred-ui/deploys/612f1007e5e5dc00076088b8 😎 Browse the preview: https://deploy-preview-434--ingred-ui.netlify.app |
TODO:
|
レビュー可能になった気がするのでどなたかお願いします。 |
今日のお昼あけあたりにみます! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
とりあえずこんなところでしょうか。
基本相談っぽい感じになりましたが、説明が足りない場合はどんどん聞いちゃってください!
@@ -0,0 +1,3 @@ | |||
import styled from "styled-components"; | |||
|
|||
export const Container = styled.div``; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yarn generate
していただいたと思うのですが、不要なら消しちゃう方針で大丈夫です:+1:
defaultProps: { activeText: "开", inActiveText: "关" }, | ||
}, | ||
ConfirmModal: { | ||
defaultProps: { confirmText: "确认", cancelText: "取消" }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
取消だけ読めた..w
src/utils/useLocaleProps.ts
Outdated
const defaultProps = locale?.components?.[name].defaultProps; | ||
let propName; | ||
|
||
for (propName in defaultProps) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
自分はいつも下記のような書き方をするのですが、letを用いる/用いないでなにか差が出たりしますか..?(純粋に気になっただけです)
for (propName in defaultProps) { | |
for (const propName in defaultProps) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hoistingも一度しか起きないしブロックスコープでconstを再定義するよりも早くなる余地があるからです。(実務上の件数ではおそらく計測不能なほどの高速化ですが)
…と思ったけど試したことがないので
// 準備
const PROPS_COUNT = 100000;
const props = {};
for (let i = 0; i < PROPS_COUNT; i++) {
props[i.toString()] = i.toString();
}
// constのやつ
console.time();
for (const outKey in props) {
// doSomething
}
console.timeEnd(); // default: 9.113037109375 ms
// letのやつ
console.time();
let outKey
for (outKey in props) {
// doSomething
}
console.timeEnd(); // default: 6.7509765625 ms
どうでしょう!
初回のテストではやはり letのほうが高速 でした!
・・・というのが初回のテストだったんですが、初回がチャンピオンデータだったようで
再読込するたびにほぼ同じになったり、constのほうが高速になったり、逆だったり、ばらつきが激しいです。
デバッグコンソールの実行では? 読み込み時では? といろいろ試したもののばらつきは変わらず。
https://codepen.io/kohashi/pen/GRERMVw とかで書いてみたけど
ちなみに node ( v15.13.0 ) でもためしてみました。こちらは安定していて
default: 14.598ms // constのほう
default: 7.452ms // letのほう
let のほうが早い! しかもダブルスコアで!!!
しかし、ふと古いnodeだとどうだろう?と思い v8.17.0 (特に理由はなくなんとなく v8 latest)で試すと
undefined: 8.979ms // constのほう
undefined: 8.476ms // letのほう
・・・ 🤔
まぁ console.time
の仕様が違うくらい昔なので何らかの実装が違うようでした。
というわけで「実務上差がないレベルで let 使ったほうが早いと思ったんだけど、計測してみたらなんかブロックスコープの生成か何かが実装によってバラバラっぽいため速度もバラバラ。node v15では安定して早いっぽいが」
そんな感じでした。
src/utils/useLocaleProps.ts
Outdated
if (output[propName] === undefined) { | ||
output[propName] = defaultProps[propName]; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
type HogeProps = {
hoge: {
text: "hogehoge";
someValue: true;
}
};
こんな感じのネストした値には対応できていない気がするのですがどうでしょう...?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://github.com/TehShrike/deepmerge
このnpmで説明できるかは微妙ですが、オブジェクト同士をマージするような形式(undefined
の場合のみ上書き)みたいなやり方が良いかなぁ今の所思っております!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
propsのマージ、 shallow merge, or deep merge の話ですよね。
ここはshallowでいいんじゃないかって思ってました。
const ToggleButton: React.FunctionComponent<ToggleButtonProps> = ({
activeText = "ON", // propsを受けてデフォ値を代入する、というのと、l10nはよく似ている
hoge = { text: "hogehoge", someValue: true} // こういうのと感覚的には同じだから、shallowがよりよいんじゃないかなって
}) => {
// ....
速度的な観点もありはするものの、基本的にはl10nする側の定義は大きくないので、deepmergeが必要ならやってもよいとは思いますー。
(MUIはシャローマージにしているものの、だから使い勝手悪くてあまり定義がないのか、そもそも基本UIフレームワークにl10nが必要な文字ってそんなに無いのでは?ということなのかの意図は判然としない…後者の気がしますが)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
そもそも基本UIフレームワークにl10nが必要な文字ってそんなに無いのでは?
なるほど、MUIもshallowなのですね。
deepmergeへ途中から変更するのもそこまで難しくないので、現段階ではshallowでいく、というので良い気がしました!
ここ書いてて思ったのですが、<MultipleFilter />
も対応が必要そうですね。
src/utils/useLocaleProps.ts
Outdated
* @param params | ||
* @returns localized Props. | ||
*/ | ||
export function useLocaleProps<T>(params: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
この"カスタムフック"に該当するものはhooks/
に集めているのでそちらに移動しても良さそうです:+1:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hoooksのほうがベター。なるほどです。移しますー
}; | ||
} | ||
|
||
export const jaJP: Localization = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
このあたりの変数、ライブラリの利用者からも使えるようにする方が良い気がしておりまして。
src/index.tsx
あたりからexport
すると良さそうです!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
exportしましたー
}; | ||
|
||
return ( | ||
<LocaleProvider locale={locales[localeOption.value]}> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
【相談】
storybookで書けているので良いかなぁと思いつつも、READMEの方も<LocaleProvider />
を用いるようにしたら親切かなと思うのですがどうですかね...?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
どうでしょうね。。
READMEには最小限だけ書いて、別途docsをしっかり書くのが流行りというか主流ですが、今はstorybookがDocs代わりになってるならいらないのでは?とも思ったりします。
「あんまりl10n周りを READMEの最初にガッツリ書かないよなー」くらいの温度感です。
一旦 残りを整理
|
EditFilterCard, FilterCard, かな |
EditFilterCard
FilterCard
違いは editButtonTitleかapplyButtonTitleかの違いかな。 |
すごい大変だった…。 @youchann お元気になったらレビューお願いします。議論になりそうなとこはコードにコメントしておきます。 |
title: "把文件拖入, 同样支持点击上传。", | ||
}, | ||
}, | ||
ItemEmpty: { defaultProps: { title: "未找到。" } }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
翻訳する量が増えちゃったのと、中国語チェックしてくれるヒトが忙しくなっちゃったので、中国語版は半分くらいしかない…。
); | ||
const ItemEmpty: React.FunctionComponent<ItemEmptyProps> = (inProps) => { | ||
const props = useLocaleProps({ props: inProps, name: "ItemEmpty" }); | ||
const { title = "Not found.", subtitle, emptyImage, imageWidth = 80 } = props; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ItemEmpty の NotFound も useLocaleProps
の対象にしました。
@@ -212,7 +218,7 @@ const MultipleFilter: React.FunctionComponent<MultipleFilterProps> = ({ | |||
ref={setInputElement} | |||
readOnly | |||
type="text" | |||
placeholder={placeholder ?? "Add a new filter"} | |||
placeholder={placeholder} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
こういう ??
Nullish Coalescing だったところを、 props = 'Default Value'
に移す & useLocaleProps
で上書きみたいなことを何箇所かでやっています。
?? "
と || "
で検索したのでl10n必要なとこは一旦埋めた気がするけど、まだ大きくあれば一旦マージして別PRにて対応したく…
@@ -187,7 +195,7 @@ export const FilterCard: React.FunctionComponent<Props> = ({ | |||
{selectedFilter && ( | |||
<div> | |||
<Typography weight="bold" size="lg"> | |||
{filter?.conditionTitle || "Condition"} | |||
{filter?.conditionTitle || conditionTitle} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ここが一番迷ったんですが、 conditionTitle
, sectionTitle
は props に移設しました。
props に移設しないやり方としては、
FilterCard: {
defaultProps: {
applyButtonTitle: "適用",
inputErrorText: "入力してください",
formPlaceholder: "検索",
sectionTitle: "セクション",
conditionTitle: "条件",
},
},
// ↓
FilterCard: {
defaultProps: {
applyButtonTitle: "適用",
inputErrorText: "入力してください",
formPlaceholder: "検索",
},
texts: {
sectionTitle: "セクション",
conditionTitle: "条件",
},
},
こんな風にすることも考えたんですが、一旦propsに統一したほうが利用者側でカスタマイズが容易で良いかな、と。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTMです!
@@ -0,0 +1,3 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
|
|||
exports[`LocaleProvider component testing LocaleProvider 1`] = `<DocumentFragment />`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
思えばProviderって実態の無いUIなのでスナップショットも不要な気がしますね!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
確かにそうだなって感じたので、スナップショット除外して生成出来るかだけのテスト(toBeTruthy)にしました!
セルフマージしちゃっていいのかな |
reviewed になったら権限あるひとはセルフマージしてるな。よーししちゃうぞー |
Ref #312
Check List (If️ you added new component in this PR)
src/components/index.ts
.storybook/documents/Information/Samples/Samples.stories.tsx